Coder Social home page Coder Social logo

rustface's People

Contributors

atomashpolskiy avatar hdhoang avatar jjhbw avatar kornelski avatar lex148 avatar mashedcode avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rustface's Issues

Meaning of score

What is the meaning of the Faceinfo::score() data?

As in, what's the range (0-10?), how is it calculated and what does it mean?

error: Could not compile `regex`. when trying to run test.sh

rustc --version
rustc 1.25.0-nightly (3f92e8d89 2018-01-14)

$./bin/test.sh /home/johnh/gits/rustfacegitmaster/rustface/examples/
./bin/test.sh: 4: ./bin/test.sh: [[: not found
./bin/test.sh: 10: ./bin/test.sh: [[: not found
Using as the working directory
Compiling regex v1.0.4
error[E0433]: failed to resolve. Could not find arch in std
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:3:10
|
3 | use std::arch::x86_64::*;
| ^^^^ Could not find arch in std

error[E0433]: failed to resolve. Could not find arch in std
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:3:10
|
3 | use std::arch::x86_64::*;
| ^^^^ Could not find arch in std

error: cannot find macro is_x86_feature_detected! in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:11:12
|
11 | if is_x86_feature_detected!("avx2") {
| ^^^^^^^^^^^^^^^^^^^^^^^

error: cannot find macro is_x86_feature_detected! in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:23:12
|
23 | if is_x86_feature_detected!("ssse3") {
| ^^^^^^^^^^^^^^^^^^^^^^^

error[E0412]: cannot find type __m256i in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:60:13
|
60 | vector: __m256i,
| ^^^^^^^ not found in this scope

error[E0425]: cannot find function _mm256_set1_epi8 in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:67:25
|
67 | u8x32 { vector: _mm256_set1_epi8(n as i8) }
| ^^^^^^^^^^^^^^^^ not found in this scope

error[E0412]: cannot find type __m256i in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:78:55
|
78 | let p = slice.as_ptr() as *const u8 as *const __m256i;
| ^^^^^^^ not found in this scope

error[E0425]: cannot find function _mm256_loadu_si256 in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:79:25
|
79 | u8x32 { vector: _mm256_loadu_si256(p) }
| ^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0412]: cannot find type __m256i in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:91:55
|
91 | let p = slice.as_ptr() as *const u8 as *const __m256i;
| ^^^^^^^ not found in this scope

error[E0425]: cannot find function _mm256_load_si256 in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:92:25
|
92 | u8x32 { vector: _mm256_load_si256(p) }
| ^^^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function _mm256_shuffle_epi8 in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:111:29
|
111 | u8x32 { vector: _mm256_shuffle_epi8(self.vector, indices.vector) }
| ^^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function _mm256_cmpeq_epi8 in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:119:25
|
119 | let boolv = _mm256_cmpeq_epi8(self.vector, other.vector);
| ^^^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function _mm256_set1_epi8 in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:120:24
|
120 | let ones = _mm256_set1_epi8(0xFF as u8 as i8);
| ^^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function _mm256_andnot_si256 in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:121:29
|
121 | u8x32 { vector: _mm256_andnot_si256(boolv, ones) }
| ^^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function _mm256_and_si256 in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:129:29
|
129 | u8x32 { vector: _mm256_and_si256(self.vector, other.vector) }
| ^^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function _mm256_movemask_epi8 in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:137:13
|
137 | _mm256_movemask_epi8(self.vector) as u32
| ^^^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function _mm256_permute2x128_si256 in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:151:21
|
151 | let v = _mm256_permute2x128_si256(other.vector, self.vector, 0x21);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function _mm256_alignr_epi8 in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:152:21
|
152 | let v = _mm256_alignr_epi8(self.vector, v, 14);
| ^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function _mm256_permute2x128_si256 in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:167:21
|
167 | let v = _mm256_permute2x128_si256(other.vector, self.vector, 0x21);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function _mm256_alignr_epi8 in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:168:21
|
168 | let v = _mm256_alignr_epi8(self.vector, v, 15);
| ^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function _mm256_srli_epi16 in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/avx2.rs:177:29
|
177 | u8x32 { vector: _mm256_srli_epi16(self.vector, 4) }
| ^^^^^^^^^^^^^^^^^ not found in this scope

error[E0412]: cannot find type __m128i in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:81:13
|
81 | vector: __m128i,
| ^^^^^^^ not found in this scope

error[E0425]: cannot find function _mm_set1_epi8 in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:88:25
|
88 | u8x16 { vector: _mm_set1_epi8(n as i8) }
| ^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function _mm_loadu_si128 in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:99:17
|
99 | let v = _mm_loadu_si128(slice.as_ptr() as *const u8 as *const __m128i);
| ^^^^^^^^^^^^^^^ not found in this scope

error[E0412]: cannot find type __m128i in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:99:71
|
99 | let v = _mm_loadu_si128(slice.as_ptr() as *const u8 as *const __m128i);
| ^^^^^^^ not found in this scope

error[E0425]: cannot find function _mm_load_si128 in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:112:17
|
112 | let v = _mm_load_si128(slice.as_ptr() as *const u8 as *const __m128i);
| ^^^^^^^^^^^^^^ not found in this scope

error[E0412]: cannot find type __m128i in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:112:70
|
112 | let v = _mm_load_si128(slice.as_ptr() as *const u8 as *const __m128i);
| ^^^^^^^ not found in this scope

error[E0425]: cannot find function _mm_shuffle_epi8 in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:132:29
|
132 | u8x16 { vector: _mm_shuffle_epi8(self.vector, indices.vector) }
| ^^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function _mm_cmpeq_epi8 in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:140:25
|
140 | let boolv = _mm_cmpeq_epi8(self.vector, other.vector);
| ^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function _mm_set1_epi8 in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:141:24
|
141 | let ones = _mm_set1_epi8(0xFF as u8 as i8);
| ^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function _mm_andnot_si128 in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:142:29
|
142 | u8x16 { vector: _mm_andnot_si128(boolv, ones) }
| ^^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function _mm_and_si128 in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:150:29
|
150 | u8x16 { vector: _mm_and_si128(self.vector, other.vector) }
| ^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function _mm_movemask_epi8 in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:158:13
|
158 | _mm_movemask_epi8(self.vector) as u32
| ^^^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function _mm_alignr_epi8 in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:166:29
|
166 | u8x16 { vector: _mm_alignr_epi8(self.vector, other.vector, 14) }
| ^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function _mm_alignr_epi8 in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:174:29
|
174 | u8x16 { vector: _mm_alignr_epi8(self.vector, other.vector, 15) }
| ^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function _mm_srli_epi16 in this scope
--> /home/johnh/.cargo/registry/src/github.com-1ecc6299db9ec823/regex-1.0.4/src/vector/ssse3.rs:182:29
|
182 | u8x16 { vector: _mm_srli_epi16(self.vector, 4) }
| ^^^^^^^^^^^^^^ not found in this scope

OS: Ubuntu 18.10 cosmic
Kernel: x86_64 Linux 4.18.0-13-generic
Uptime: 1h 9m
Packages: 2393
Shell: bash 4.4.19
Resolution: 1920x1200
DE: LXDE
WM: OpenBox
CPU: Intel Xeon W-2125 @ 8x 4.5GHz [36.0°C]
GPU: Quadro P4000
RAM: 2811MiB / 31821MiB

Re-evaluate parallelization (Rayon)

Seems lik the --no-default-features flag (which disables Rayon multiprocessing) actually leads to a serious speedup of detect(), from ~1000 ms to ~700 ms on the scientists.jpg image. Likely due to shaving off threading overhead. This is on a noisy dual core 2018 MBP, so YMMV.

I think larger images may benefit more from parallel processing, let's test that first. We may need to re-evaluate whether we want parallel processing on by default.

SIMD State and feature flag

Hi! This library looks awesome.
I'm a little confused. Does the stable version include SIMD?
I'd like to use this with wasm, which does not support SIMD yet. Is it only in the nightly branch, or is there a way to deactivate it?

Attempt to subtract with overflow error

Hey, I'm getting a Attempt to subtract with overflow error on some images.

One such file is attached below.

Code:

const MODEL_SEETA_FD_FRONTAL: &'static [u8] = include_bytes!("./seeta_fd_frontal_v1.0.bin");


fn face_detector() -> Box<rustface::Detector> {
    let model = rustface::read_model(MODEL_SEETA_FD_FRONTAL.to_vec()).unwrap();
    rustface::create_detector_with_model(model)
}

pub fn face_detect<P>(
    path: P
) -> Result<Option<image::DynamicImage>, failure::Error>
    where P: AsRef<std::path::Path>
{
    use image::Pixel;

    let path = path.as_ref();

    let mut detector = face_detector();

    // Load the image.
    let mut image: image::DynamicImage = image::open(path)?;

    //        let rgb = image.clone().to_rgb();
    let gray = image.to_luma();
    let (width, height) = gray.dimensions();
    let mut grey_image = rustface::ImageData::new(gray.as_ptr(), width, height);
    let mut faces = detector.detect(&mut grey_image);

    dbg!(("Detected faces in image", &path, &faces,));

    if faces.len() == 1 {
        let info = faces.get(0).unwrap();
        let grid = &info.bbox();
        // Detected exactly one face!
        let face_image = image.crop(
            grid.x() as u32,
            grid.y() as u32,
            grid.width() as u32,
            grid.height() as u32,
        );

        Ok(Some(image))
    } else {
        Ok(None)
    }
}

Backtrace:

thread '<unnamed>' panicked at 'attempt to subtract with overflow', /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rustface-0.1.2/src/math/mod.rs:56:31
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.29/src/backtrace/libunwind.rs:88
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.29/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:47
   3: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:36
   4: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:198
   5: std::panicking::default_hook
             at src/libstd/panicking.rs:212
   6: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:475
   7: std::panicking::continue_panic_fmt
             at src/libstd/panicking.rs:382
   8: rust_begin_unwind
             at src/libstd/panicking.rs:309
   9: core::panicking::panic_fmt
             at src/libcore/panicking.rs:85
  10: core::panicking::panic
             at src/libcore/panicking.rs:49
  11: rustface::math::vector_sub
             at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rustface-0.1.2/src/math/mod.rs:56
  12: rustface::feat::surf_mlp_featmap::SurfMlpFeatureMap::compute_grad_y::{{closure}}
             at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rustface-0.1.2/src/feat/surf_mlp_featmap.rs:153
  13: <rayon::iter::for_each::ForEachConsumer<F> as rayon::iter::plumbing::Folder<T>>::consume_iter::{{closure}}
             at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.1.0/src/iter/for_each.rs:55
  14: core::iter::traits::iterator::Iterator::fold::{{closure}}
             at /rustc/5f3656ce9a2212fad872605b7a4ee103a155e9f3/src/libcore/iter/traits/iterator.rs:1685
  15: core::iter::traits::iterator::Iterator::try_fold
             at /rustc/5f3656ce9a2212fad872605b7a4ee103a155e9f3/src/libcore/iter/traits/iterator.rs:1573
  16: core::iter::traits::iterator::Iterator::fold
             at /rustc/5f3656ce9a2212fad872605b7a4ee103a155e9f3/src/libcore/iter/traits/iterator.rs:1685
  17: <rayon::iter::for_each::ForEachConsumer<F> as rayon::iter::plumbing::Folder<T>>::consume_iter
             at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.1.0/src/iter/for_each.rs:55
  18: rayon::iter::plumbing::Producer::fold_with
             at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.1.0/src/iter/plumbing/mod.rs:110
  19: rayon::iter::plumbing::bridge_producer_consumer::helper
             at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.1.0/src/iter/plumbing/mod.rs:438
  20: rayon::iter::plumbing::bridge_producer_consumer::helper::{{closure}}
             at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.1.0/src/iter/plumbing/mod.rs:427
  21: rayon_core::join::join_context::{{closure}}::{{closure}}
             at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.5.0/src/join/mod.rs:127
  22: <rayon_core::job::StackJob<L,F,R> as rayon_core::job::Job>::execute::{{closure}}
             at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.5.0/src/job.rs:115
  23: <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
             at /rustc/5f3656ce9a2212fad872605b7a4ee103a155e9f3/src/libstd/panic.rs:309
  24: std::panicking::try::do_call
             at /rustc/5f3656ce9a2212fad872605b7a4ee103a155e9f3/src/libstd/panicking.rs:294
  25: __rust_maybe_catch_panic
             at src/libpanic_unwind/lib.rs:85
  26: std::panicking::try
             at /rustc/5f3656ce9a2212fad872605b7a4ee103a155e9f3/src/libstd/panicking.rs:273
  27: std::panic::catch_unwind
             at /rustc/5f3656ce9a2212fad872605b7a4ee103a155e9f3/src/libstd/panic.rs:388
  28: rayon_core::unwind::halt_unwinding
             at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.5.0/src/unwind.rs:17
  29: <rayon_core::job::StackJob<L,F,R> as rayon_core::job::Job>::execute
             at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.5.0/src/job.rs:115
  30: rayon_core::job::JobRef::execute
             at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.5.0/src/job.rs:59
  31: rayon_core::registry::WorkerThread::execute
             at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.5.0/src/registry.rs:734
  32: rayon_core::registry::WorkerThread::wait_until_cold
             at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.5.0/src/registry.rs:718
  33: rayon_core::registry::WorkerThread::wait_until
             at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.5.0/src/registry.rs:692
  34: rayon_core::registry::main_loop
             at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.5.0/src/registry.rs:812
  35: rayon_core::registry::ThreadBuilder::run
             at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.5.0/src/registry.rs:58
  36: <rayon_core::registry::DefaultSpawn as rayon_core::registry::ThreadSpawn>::spawn::{{closure}}
             at /home/theduke/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.5.0/src/registry.rs:103
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
test detect::detect_faces ... FAILED

twitch_preview_1

Bringing back explicit SIMD to the stable branch

The way explicit SIMD is used in the rustface nightly branch is currently not compatible with stable rust (only with an old nightly version, see README).

As the SIMD features used in the rustface nightly branch slowly reach stable rust, we can think of bringing these features back to the master branch.

If eventually the stable Rust SIMD API turns out to have changed beyond what we can comfortably salvage from old code in rustface's nightly branch, we can look at using a library that abstracts the nitty gritty for us, like faster (when it is stable).

Tracking issue for SIMD support in stable Rust: rust-lang/rust#27731

Moving to stable rustc 1.28

Hi Andrei,

Following up on #8 , I made a little bit of progress.

Bad news: the faster crate is still unstable. While it would have been very useful, having to stay on nightly is a bit of a dealbreaker for me. If I want SIMD, I'm afraid it needs to be explicit for now.

First I wanted to investigate whether explicit SIMD is still worth it with all the compiler improvements that were introduced since rustc 1.25 nightly (latest version on which the rustface master branch works, according to Travis).

To get a quick-and-dirty answer to this question, I did the following:

  • I cut out all code that was incompatible with rustc 1.28.0 stable (that is: mostly reverting to your portable implementations of the vector math, and removing their counterparts that used explicit SIMD). See the only_stable_features branch.
  • I spun up a n1-standard-4 (4 vCPUs, 15 GB memory) in GCP.
  • I built the binaries of the image_demo example for master using rustc 1.25 nightly, and for my only_stable_features branch using rustc 1.28 stable.
  • I simply compared the runtime of these binaries from the command line, also testing the impact of the number of available Rayon threads. Note that this includes the execution time of importing the model and test image.

This yielded the following results:

Command Mean [ms] Min…Max [ms]
RAYON_NUM_THREADS=1 ./image_demo_master_nightly_1.25.0 model/seeta_fd_frontal_v1.0.bin assets/test/scientists.jpg 1238.2 ± 85.0 1136.6…1374.6
RAYON_NUM_THREADS=1 ./image_demo_stable_1.28.0 model/seeta_fd_frontal_v1.0.bin assets/test/scientists.jpg 1440.8 ± 81.5 1322.2…1581.9
RAYON_NUM_THREADS=2 ./image_demo_master_nightly_1.25.0 model/seeta_fd_frontal_v1.0.bin assets/test/scientists.jpg 1242.0 ± 34.2 1198.7…1344.9
RAYON_NUM_THREADS=2 ./image_demo_stable_1.28.0 model/seeta_fd_frontal_v1.0.bin assets/test/scientists.jpg 1301.2 ± 15.4 1273.5…1323.7
RAYON_NUM_THREADS=3 ./image_demo_master_nightly_1.25.0 model/seeta_fd_frontal_v1.0.bin assets/test/scientists.jpg 1278.0 ± 16.4 1246.8…1311.2
RAYON_NUM_THREADS=3 ./image_demo_stable_1.28.0 model/seeta_fd_frontal_v1.0.bin assets/test/scientists.jpg 1328.4 ± 13.4 1309.0…1354.5

In words, that means:
'RAYON_NUM_THREADS=1 ./image_demo_master_nightly_1.25.0' ran
1.00x faster than 'RAYON_NUM_THREADS=2 ./image_demo_master_nightly_1.25.0'
1.03x faster than 'RAYON_NUM_THREADS=3 ./image_demo_master_nightly_1.25.0'
1.05x faster than 'RAYON_NUM_THREADS=2 ./image_demo_stable_1.28.0'
1.07x faster than 'RAYON_NUM_THREADS=3 ./image_demo_stable_1.28.0'
1.16x faster than 'RAYON_NUM_THREADS=1 ./image_demo_stable_1.28.0'

I guess this means master is still about ~20% faster than the 1.28 version without explicit SIMD, as could be expected. Adding more Rayon threads to 1.28 seems to compensate the difference a little bit.

As a side investigation, I also checked whether recent improvements in autovectorization may have obsoleted the need for some of your unsafe portable vector math functions. As expected, your functions are still the fastest:

The square function:

square

The abs function:
abs

Exact code used for all the above benchmarks can be found in the README of only_stable_features.

Merging only_stable_features would offer a quick-and-dirty way to become compatible with stable rust, but at the cost of a performance hit. For my use case, the perf hit is fine, but you may not like it for the main lib.

As mentioned in #7 (comment), the new stable SIMD intrinsics may help, depending on how complete they are.
I can give refactoring a try when I find the time.

Let me know what you think.

Error detect image

I'm testing using the example, but I get an error, this is the code, what am I doing wrong?

fn detect_faces(path: &String) {
    let image: DynamicImage = match image::open(path) {
        Ok(image) => image,
        Err(message) => {
            println!("Failed to read image: {}", message);
            std::process::exit(1)
        }
    };

    let img_luma = &image.to_luma8();
    let (width, height) = img_luma.dimensions();

    let mut detector =
        rustface::create_detector("./files/model/seeta_fd_frontal_v1.0.bin").unwrap();
    detector.set_min_face_size(20);
    detector.set_score_thresh(2.0);
    detector.set_pyramid_scale_factor(0.8);
    detector.set_slide_window_step(4, 4);

    let mut image_data = ImageData::new(&img_luma, width, height);

    let faces = detector.detect(&mut image_data);

    //println!("faces {:?}", faces); //<- This generate error 

    println!("Found {} faces in", faces.len()); //<- This generate error 

} 

Call function

 detect_faces("./files/images/scientists.jpg");

Error

thread '<unnamed>' panicked at 'attempt to subtract with overflow', /home/benjamin/.cargo/registry/src/github.com-1ecc6299db9ec823/rustface-0.1.6/src/math/mod.rs:48:27
stack backtrace:
   0:     0x55562010ddf0 - std::backtrace_rs::backtrace::libunwind::trace::h72c2fb8038f1bbee
                               at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/../../backtrace/src/backtrace/libunwind.rs:96
   1:     0x55562010ddf0 - std::backtrace_rs::backtrace::trace_unsynchronized::h1e3b084883f1e78c
                               at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/../../backtrace/src/backtrace/mod.rs:66
   2:     0x55562010ddf0 - std::sys_common::backtrace::_print_fmt::h3bf6a7ebf7f0394a
                               at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/sys_common/backtrace.rs:79
   3:     0x55562010ddf0 - <std::sys_common::backtrace::_print::DisplayBacktrace as 

....

Note
Update the example code

Cannot install rustface even when using nightly Rust

Hi,

I am using the nightly build of Rust:

rustup 1.11.0 (e751ff9f8 2018-02-13)
rustc 1.28.0-nightly (f28c7aef7 2018-06-19)
cargo 1.28.0-nightly (e2348c2db 2018-06-07)

but when I try to install rustface, I get this error:

232 | #[target_feature = "+tbm"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^

error: #[target_feature] attribute must be of the form #[target_feature(..)]
   --> /Users/user/.cargo/registry/src/github.com-1ecc6299db9ec823/stdsimd-0.0.3/src/x86/tbm.rs:244:1
    |
244 | #[target_feature = "+tbm"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^

error: #[target_feature] attribute must be of the form #[target_feature(..)]
   --> /Users/user/.cargo/registry/src/github.com-1ecc6299db9ec823/stdsimd-0.0.3/src/x86/tbm.rs:255:1
    |
255 | #[target_feature = "+tbm"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 750 previous errors

error: Could not compile `stdsimd`.
warning: build failed, waiting for other jobs to finish...
error: failed to compile `rustface v0.1.0`, intermediate artifacts can be found at `/var/folders/pz/45htc8zn6_sbd3411btr4pq40000gp/T/cargo-installGrNVuk

How do you switch to Rust nightly toolchain?

As per my question in issue #5 I was recommended to use the nightly Rust toolchain. Any chance you can tell me where I can that from? At the moment I am using the one from the official website. Do I have to build it myself?

compare

Hi, I'm learning how to use this library. How should I compare it with another graph?

Parallelize CPU intensive loops

The original version uses OpenMP for parallelization, in 6 places in total. So far I've been able to use Rayon to modify the corresponding code in the Rust version, in 2 places:

(1)
MLPLayer::Compute (src/classifier/mlp.cpp:39)
classifier::surf_mlp_classifier::Layer::compute (src/classifier/surf_mlp_classifier.rs:153)

(2)
SURFFeatureMap::ComputeGradY (src/feat/surf_feature_map.cpp:197)
feat::surf_mlp_featmap::SurfMlpFeatureMap::compute_grad_y (src/feat/surf_mlp_featmap.rs:137)

Here are the remaining places:

(3)
SURFFeatureMap::ComputeGradX (src/feat/surf_feature_map.cpp:178)
feat::surf_mlp_featmap::SurfMlpFeatureMap::compute_grad_x (src/feat/surf_mlp_featmap.rs:116)

(4)
LABFeatureMap::ComputeRectSum (src/feat/lab_feature_map.cpp:145)
feat::lab_boosted_featmap::LabBoostedFeatureMap::compute_rect_sum (feat/lab_boosted_featmap.rs:183)

(5)
LABFeatureMap::ComputeFeatureMap (src/feat/lab_feature_map.cpp:173)
feat::lab_boosted_featmap::LabBoostedFeatureMap::compute_feature_map (feat/lab_boosted_featmap.rs:215)

(6)
fd::ResizeImage (include/util/image_pyramid.h:44)
common::resize_image (common/image_pyramid.rs:175)

Allow re-use of Model

Re-using a model currently requires copying the file bytes and re-parsing; this seems wasteful. Perhaps Model can be made .clone()able?

Off by one?

I'm wondering why this code has (feature_id - 1):

for &feature_id in &self.feature_ids[..] {
feature_map.get_feature_vector((feature_id - 1) as usize, dest);
let offset = feature_map.get_feature_vector_dim(feature_id as usize);
dest = dest.offset(offset as isize);
}

shouldn't it advance the pointer by the size of the same feature vector that has been copied, not the next one?

Could not install rustface because of stdsimd

I am on Ubuntu 18 and I am trying to install rustface using cargo:
cargo install rustface


but I get this error:
Installing rustface v0.1.0
   Compiling stdsimd v0.0.3
error[E0554]: #![feature] may not be used on the stable release channel
   --> /home/user1/.cargo/registry/src/github.com-1ecc6299db9ec823/stdsimd-0.0.3/src/lib.rs:121:1
    |
121 | / #![feature(const_fn, link_llvm_intrinsics, platform_intrinsics, repr_simd,
122 | |            simd_ffi, target_feature, cfg_target_feature, i128_type, asm,
123 | |            const_atomic_usize_new, stmt_expr_attributes)]
    | |_________________________________________________________^

error: aborting due to previous error

error: failed to compile `rustface v0.1.0`, intermediate artifacts can be found at `/tmp/cargo-install.9nKgAONhib5s`

Caused by:
  Could not compile `stdsimd`.

To learn more, run the command again with --verbose.

Any idea how to fix it?
I am using:
cargo 0.26.0
rustc 1.24.1

error when build

`error: #[target_feature] attribute must be of the form #[target_feature(..)]
--> C:\Users\Administrator.cargo\registry\src\mirrors.ustc.edu.cn-61ef6e0cd06fb9b8\stdsimd-0.0.3\src\x86\tbm.rs:232:1
|
232 | #[target_feature = "+tbm"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^

error: #[target_feature] attribute must be of the form #[target_feature(..)]
--> C:\Users\Administrator.cargo\registry\src\mirrors.ustc.edu.cn-61ef6e0cd06fb9b8\stdsimd-0.0.3\src\x86\tbm.rs:244:1
|
244 | #[target_feature = "+tbm"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^

error: #[target_feature] attribute must be of the form #[target_feature(..)]
--> C:\Users\Administrator.cargo\registry\src\mirrors.ustc.edu.cn-61ef6e0cd06fb9b8\stdsimd-0.0.3\src\x86\tbm.rs:255:1
|
255 | #[target_feature = "+tbm"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 750 previous errors

error: Could not compile stdsimd.
warning: build failed, waiting for other jobs to finish...
error: build failed`

Out-of-bounds memory read from src/feat/surf_mlp_featmap.rs#L165

Random attempt to subtract with overflow panic on src/math/mod.rs#L48 (math::vector_sub).

Panic is caused by trying to calculate -2147483648 - 215.

Can't produce minimal reproducible. What seems to happen is that the last call to vector_sub in the for_each tries to access out of bound memory which randomly happens to contain the value -2147483648 in my case.

Backtraces to detect call. Code that panics is pretty much the same as in image_demo.rs.

Webassembly - Assertion panics

When compiling to webassembly ( --target wasm32-wasi ) detection always results in an assertion failure.

thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `826165`,
 right: `743000`', cargo/registry/src/github.com-1ecc6299db9ec823/rustface-0.1.6/src/common/image_pyramid.rs:32:9

Can I help upgrading to the stable 1.28 toolchain?

Hi @atomashpolskiy ,

Cool project! Looking forward to testing it out in a side project.
However, the current dependency on stdsimd and an old nightly toolchain is a bit of a dealbreaker.

If I find the time, do you mind if I have a go at porting the current code to stable rustc 1.28?

You probably already put some thought into this. What is your opinion on using a crate like faster to abstract away the explicit SIMD work? That way rustface stays up to date on any future improvements to Rust's SIMD intrinsics for free.

Let me know your thoughts!

Update crates.io

Hi Andrei,

I incremented the version number and a few dependencies.

I researched the API a bit, and I think it is most 'effort-efficient' if we move refactoring explicit SIMD support to the long term. I made a tracking issue for that (#10).

If you agree with these changes, can you run cargo publish on master?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.