These are chat archives for rust-lang/rust

27th
Jun 2018
prataprc
@prataprc
Jun 27 2018 04:13
@tsoernes for loops are syntactic sugar for match. And AFAIK, if arr implements IntoIterator trait (into_iter) arr.into_iter() can be replaced by arr.
Fredrik Portström
@portstrom
Jun 27 2018 07:32
How can I measure the CPU time used by a thread? I don't mind if the solution is Linux-specific.
tsoernes
@tsoernes
Jun 27 2018 07:41
how to do ndarray type conversions?
    let mut n_used: Array1<usize> = Array::zeros(CHANNELS);
    let grid: Array1<bool> = Array::default(CHANNELS);
    //  the trait bound `ndarray::ArrayBase<ndarray::OwnedRepr<usize>, ndarray::Dim<[usize; 1]>>: std::convert::From<ndarray::ArrayBase<ndarray::OwnedRepr<bool>, ndarray::Dim<[usize; 1]>>>` is not satisfied (the trait `std::convert::From<ndarray::ArrayBase<ndarray::OwnedRepr<bool>, ndarray::Dim<[usize; 1]>>>` is not implemented for `ndarray::ArrayBase<ndarray::OwnedRepr<usize>, ndarray::Dim<[usize; 1]>>`) (rust-cargo)
    let g: Array1<usize> = grid.into();
    n_used = n_used + g;
Michal 'vorner' Vaner
@vorner
Jun 27 2018 07:58
@portstrom clock_gettime with CLOCK_THREAD_CPUTIME_ID could work
or pthread_getcpuclockid seems like another start
Fredrik Portström
@portstrom
Jun 27 2018 08:01
@vorner So I need to call C functions?
Fredrik Portström
@portstrom
Jun 27 2018 08:53
I'm looking for something that takes a Read and wraps it in a Read or BufRead that can be sent to another thread, still reading the inner Read in the first thread. I have an XML reader wrapping a Bzip2 reader using 100% CPU on one thread, and I would like to try running them in different threads.
Sai Zeng
@zengsai
Jun 27 2018 09:17
@tanriol got it, thanks
Sylwester Rąpała
@xoac
Jun 27 2018 09:19
Is there a way to easy convert numbers to enum?
    pub fn from_u16(raw: u16) -> Option<Cmd> {
        match raw {
            0x01 | 0x02 | 0x03 | 0x04 | 0x10 | 0x45 | 0x47 | 0x4A | 0x5A | 0x78 => unsafe {
                Some(std::mem::transmute(raw))
            },
            _ => None,
        }
    }
the problem is:
error[E0512]: transmute called with types of different sizes
  --> src/lib.rs:41:22
   |
41 |                 Some(std::mem::transmute(raw))
   |                      ^^^^^^^^^^^^^^^^^^^
   |
   = note: source type: u16 (16 bits)
   = note: target type: Cmd (8 bits)
prataprc
@prataprc
Jun 27 2018 09:20
Cmd is the enum ?
Sylwester Rąpała
@xoac
Jun 27 2018 09:21
I could match 0x01 => Cmd::TypeFor0x01.. but its a lot of work if I work with many C structures
yes Cmd is enum
prataprc
@prataprc
Jun 27 2018 09:22
if the values have valid discriminant, I think type cast will work.
Sylwester Rąpała
@xoac
Jun 27 2018 09:22
you mean u16 as Cmd?
prataprc
@prataprc
Jun 27 2018 09:22
yes.
Sylwester Rąpała
@xoac
Jun 27 2018 09:23
I would like to return Option<Cmd> like in example since with raw data I can't never be sure of proper value
Andrey Lesnikov
@ozkriff
Jun 27 2018 09:28
as can cast an enum to its descriminant, but not vice versa as that operation can fail
prataprc
@prataprc
Jun 27 2018 09:29
I see. It makes sense if value can't be validated in compile time.
But in this example, values are explicitly matched.
Sylwester Rąpała
@xoac
Jun 27 2018 09:30
I take enum-primitive-derive

But in this example, values are explicitly matched.

And what if I made mistake in one number or forgot one number? Better solution is crate linked by @ozkriff this do exactly what I want!

prataprc
@prataprc
Jun 27 2018 09:32
:+1:
Another alternative is to implement the From trait for your enum.
Sylwester Rąpała
@xoac
Jun 27 2018 09:34
that require the same
Note: this trait must not fail. If the conversion can fail, use TryFrom or a dedicated method which returns an Option<T> or a Result<T, E>.
Ingvar Stepanyan
@RReverser
Jun 27 2018 12:22
@xoac You can use external "polyfills" like https://docs.rs/try_from/0.2.2/try_from/trait.TryFrom.html in the meanwhile
tsoernes
@tsoernes
Jun 27 2018 16:48

is there a simpler way to do:

let (r,  c) = (neigh[0], neigh[1])

provided neigh is a ndarray of length 2?

Dmitriy
@dpogretskiy
Jun 27 2018 16:50
i don't think so, there were slice patterns, but atm they are either feature gated, or dicontinued
rust-lang/rust#23121
if ndarray is even sliceable
tsoernes
@tsoernes
Jun 27 2018 16:52
man, wrangling arrays is really a pain in rust compared to python/numpy ..
maybe it'll get better
Dmitriy
@dpogretskiy
Jun 27 2018 16:54
oh wait
let [a, b] = [2i32; 2];
this seems to work
as it's not a slice
tsoernes
@tsoernes
Jun 27 2018 16:54
that's a regular array not a ndarray though?
Dmitriy
@dpogretskiy
Jun 27 2018 16:55
hold my beer
:)
you mean this, right? which kind of ndarray exactly?
tsoernes
@tsoernes
Jun 27 2018 16:57
Yes, that crate. Take a Array1<usize> as an example.
&array![1, 2]
Dmitriy
@dpogretskiy
Jun 27 2018 17:00
nah, you can't
the deal is, there is an Index trait
Denis Lisov
@tanriol
Jun 27 2018 17:01
@tsoernes Do you expect them to be two views into the same array?
tsoernes
@tsoernes
Jun 27 2018 17:02
If neigh = &array![1,2] then I expect them to be 1 and 2 respectively, i.e. as it would be in python if you did a, b = [1, 2]
Dmitriy
@dpogretskiy
Jun 27 2018 17:03
but python's [1, 2] is not ndarray by any means :D
ndarray is kind of insane hackery
tsoernes
@tsoernes
Jun 27 2018 17:03
well it would work for numpy's ndarray as well, a, b = np.array([1, 2])
Dmitriy
@dpogretskiy
Jun 27 2018 17:05
well, scala would allow val NDArray(a,b,c,d,e,f,g,h,i) = NDArray(1,2) if you know what youre doing :)
it's not the case for rust tho
tsoernes
@tsoernes
Jun 27 2018 17:07

Is there a better way to do the last line of:

    let I = 10;
    let mut freps: Array1<usize> = Array::ones((I));
    let diff: isize = -1;
    let i = 1;
    freps[[i]] = (freps[[i]] as isize + diff) as usize;

Assuming to know that adding diff will always result in a positive value?

Dmitriy
@dpogretskiy
Jun 27 2018 17:08
write diff = 1 and then -diff ?
tsoernes
@tsoernes
Jun 27 2018 17:09
but if diff is fixed
Dmitriy
@dpogretskiy
Jun 27 2018 17:09
at what moment diff is fixed exactly?
is it always negative?
tsoernes
@tsoernes
Jun 27 2018 17:10
No.
Dmitriy
@dpogretskiy
Jun 27 2018 17:10
is freps[[i]] - diff always positive ?
tsoernes
@tsoernes
Jun 27 2018 17:10
Yes
or + diff rather (as above)
Diff is sometimes 1, sometimes (-1), so it has to be unsigned. But the sum is always positive.
Dmitriy
@dpogretskiy
Jun 27 2018 17:12
there are ways to do that, expectedly, but they all will cost you, how bad do you think 2 casts are?
isn't it completely irrelevant for the big picture?
tsoernes
@tsoernes
Jun 27 2018 17:13
Not that bad, just very verbose when you have 5 indecies since you need to write them twice
Dmitriy
@dpogretskiy
Jun 27 2018 17:14
if you try to extract that +-diff logic somewhere else, will it help?
you totally can if diff = -1 {freps[[i]] -= 1} else {freps[[i]] += 1}
tsoernes
@tsoernes
Jun 27 2018 17:15
I don't think so. Here's context:
/// Given a grid, its feature representation frep,
/// and a set of actions specified by cell, event type and a list of channels,
/// derive feature representations for the afterstates of grid
fn incremental_freps(
    grid: &Grid,
    frep: &Frep,
    cell: &Cell,
    ce_type: &CEType,
    chs: &[usize],
) -> Freps {
    let (r1, c1) = (cell.row, cell.col);
    let neighs4 = neighbors(4, r1, c1, false);
    let neighs2 = neighbors(2, r1, c1, true);
    let mut freps = Array::zeros((chs.len(), ROWS, COLS, CHANNELS + 1));
    freps.assign(&frep);
    let mut n_used_neighs_diff: isize = 1;
    let mut n_elig_self_diff: isize = -1;
    if *ce_type == CEType::END {
        n_used_neighs_diff = -1;
        n_elig_self_diff = 1;
    }
    for (i, ch) in chs.into_iter().enumerate() {
        for neigh in neighs4.outer_iter() {
            freps[[i, neigh[0], neigh[1], *ch]] =
                (freps[[i, neigh[0], neigh[1], *ch]] as isize + n_used_neighs_diff) as usize;
        }
        for neigh_a in neighs2.outer_iter() {
            let (r2, c2) = (neigh_a[0], neigh_a[1]);
            let neighs = neighbors(2, r2, c2, false);
            let mut not_eligible = grid[[r2, c2, *ch]];
            for neigh_b in neighs.outer_iter() {
                not_eligible |= grid[[neigh_b[0], neigh_b[1], *ch]];
            }
            if !not_eligible {
                freps[[i, neigh_a[0], neigh_a[1], CHANNELS]] =
                    (freps[[i, neigh_a[0], neigh_a[1], CHANNELS]] as isize + n_elig_self_diff)
                        as usize;
            }
        }
    }
    freps
}
Yes that would probably work.
Dmitriy
@dpogretskiy
Jun 27 2018 17:16
it's not that bad :)
also, you can totally +=
but you need to defef i believe
*freps[[i, neigh[0]]]...
tsoernes
@tsoernes
Jun 27 2018 17:20
You mean *freps[[i, neigh[0], neigh[1], *ch]] += n_used_neighs_diff? => usize cannot be dereferenced
Dmitriy
@dpogretskiy
Jun 27 2018 17:20
and without *?
let (n_used_neighs_diff, n_elig_self_diff) = if *ce_type == CEType::END {(-1, 1)} else {(1, -1)};
this can save some symbols, as well
if types won't infer and they won't since later you try to throw them into usize, you can also write 1isize
same for every primitive
5f32 = 5.0 = :f32 = 5;
Dmitriy
@dpogretskiy
Jun 27 2018 17:28
trait IncDec {
    fn i_d(&mut self, i: bool);
}

impl IncDec for usize {
    fn i_d(&mut self, i: bool) {
        if i {
            *self += 1;
        } else {
            *self -= 1;
        }
    }
}


fn main() {
    let mut u = 15usize;
    u.i_d(true);
    println!("{}", u);
    u.i_d(false);
    println!("{}", u);
}
also this works right as you expect it to
all of those are complete overkill, anyways :laughing:
tsoernes
@tsoernes
Jun 27 2018 17:47
That's good. Thank you.
Dmitriy
@dpogretskiy
Jun 27 2018 17:53
@tsoernes no problems, good luck with the hacking
tsoernes
@tsoernes
Jun 27 2018 23:59

Say I have

struct Event {
    a: i32,
    b: i32
}

Is there a way to auto derive Ord for Event based on b?