Отправка Nalgebra VectorN между потоками - PullRequest
0 голосов
/ 16 декабря 2018

Я использую тип Nalgebra VectorN<f64, N> в каком-то однопоточном коде, который работает хорошо.Сейчас я пытаюсь выполнить многопоточность различных частей алгоритма, но столкнулся с проблемами, передающими VectorN s в вызов thread::spawn.Например, следующий код не может быть скомпилирован:

use std::thread;
use nalgebra::{VectorN, DefaultAllocator, DimName};
use nalgebra::allocator::Allocator;

struct Test<N>
where
    N: DimName,
    DefaultAllocator: Allocator<f64, N>,
{
    pub field: VectorN<f64, N>,
}

impl<N> Test<N>
where
    N: DimName,
    DefaultAllocator: Allocator<f64, N>,
{
    pub fn test(&self) {
        let handle = thread::spawn(move || {
            let thing = self.field;

            let thing2 = thing * 2.0;

            thing2
        });

        let res = handle.join().unwrap();
    }
}

С этой ошибкой:

error[E0277]: `<nalgebra::base::default_allocator::DefaultAllocator as nalgebra::base::allocator::Allocator<f64, N>>::Buffer` cannot be sent between threads safely
  --> trajectories/src/path/mod.rs:34:22
   |
34 |         let handle = thread::spawn(move || {
   |                      ^^^^^^^^^^^^^ `<nalgebra::base::default_allocator::DefaultAllocator as nalgebra::base::allocator::Allocator<f64, N>>::Buffer` cannot be sent between threads safely
   |
   = help: within `nalgebra::base::matrix::Matrix<f64, N, nalgebra::base::dimension::U1, <nalgebra::base::default_allocator::DefaultAllocator as nalgebra::base::allocator::Allocator<f64, N>>::Buffer>`, the trait `std::marker::Send` is not
implemented for `<nalgebra::base::default_allocator::DefaultAllocator as nalgebra::base::allocator::Allocator<f64, N>>::Buffer`
   = note: required because it appears within the type `nalgebra::base::matrix::Matrix<f64, N, nalgebra::base::dimension::U1, <nalgebra::base::default_allocator::DefaultAllocator as nalgebra::base::allocator::Allocator<f64, N>>::Buffer>`
   = note: required by `std::thread::spawn`

Я пробовал различные определения для N и DefaultAllocator в where пункты, но не далеко.Различные поисковые системы не нашли ничего полезного в этом вопросе.

Если я заменю VectorN<f64, N> на VectorN<f64, U3> (или любой другой тип U* из Nalgebra), вышеуказанная ошибка исчезнет.Я прочитал общее руководство по программированию Nalgebra , однако это кажется устаревшим и, возможно, не тем, что мне нужно;Я не хочу завершить универсальность, просто возможность использовать VectorN с любым ограниченным размером.Какие границы черт мне нужно поместить в мою структуру, чтобы я мог передать field в поток?

1 Ответ

0 голосов
/ 17 декабря 2018

Я сделал удар в темноте (основываясь на сообщениях об ошибках, данных компилятором) и сумел сделать эту работу, добавив границы к Allocator::Buffer следующим образом:

use nalgebra::allocator::Allocator;

struct Test<N>
where
    N: DimName,
    DefaultAllocator: Allocator<f64, N>,
    <DefaultAllocator as Allocator<f64, N>>::Buffer: Send + Sync,
{
    pub field: VectorN<f64, N>,
}

// snip ...

Я неЯ уверен, что это правильный способ сделать это, и это, безусловно, добавляет некоторый шум, но теперь, похоже, я позволю передать конструкции Nalgebra в потоки.

...