Boost :: io_service post usando un lambda -- ++ campo con c++11 campo con boost campo con lambda campo con cuda camp Relacionados El problema

boost::io_service post using a lambda


1
vote

problema

Español

Esta pregunta se relaciona con este Pregunta previa .

He implementado el código publicado allí por Richard Hodges. El código publicado funciona para mí cuando uso g++ (Debian 4.8.4-1) 4.8.4 .

Sin embargo, la implementación es parte de una biblioteca de CUDA, y estoy atrapado con CUDA 6.5 que soportan de manera increíficamente características C ++ 11.

Cuando uso el código Richard publicado:

  template <class F> void submit( F&& f) {     std::unique_lock<std::mutex> lock(_cvm);     ++ _tasks;     lock.unlock();     _io_service.post(     [this, f = std::forward<F>(f)]                      {                          f();                          reduce();                      }); }   

Recibo un error: error: expected a "]" refiriéndose a la línea Lambda. Esto me hace pensar que el encabezado no está siendo analizado correctamente. Lo intenté sin la plantilla, solo pasando una referencia a la clase de mi trabajador, y sin el reenvío.

  void submit( trainer & job) {     std::unique_lock<std::mutex> lock(_cvm);     ++ _tasks;     lock.unlock();     _io_service.post([this,&]                      {                          job();                          reduce();                      }); }   

y tengo error: an enclosing-function local variable cannot be referenced in a lambda body unless it is in the capture list .

Entonces, agregué explícitamente tanto this y job :

  void submit( trainer & job) {     std::unique_lock<std::mutex> lock(_cvm);     ++ _tasks;     lock.unlock();     _io_service.post([this,&job]                      {                          job();                          reduce();                      }); }   

En qué punto, me quedé atascado en el error:

error: could not convert ‘{{((cuANN::trainer_pool*)this)->cuANN::trainer_pool::_io_service}}’ from ‘<brace-enclosed initializer list>’ to ‘boost::asio::io_service::work’ boost::asio::io_service::work _work { _io_service };

FYI, cuANN::trainer_pool es el template <class F> void submit( F&& f) { std::unique_lock<std::mutex> lock(_cvm); ++ _tasks; lock.unlock(); _io_service.post( [this, f = std::forward<F>(f)] { f(); reduce(); }); } 0 en el ejemplo de Richard, y la implementación de la piscina de richard, y template <class F> void submit( F&& f) { std::unique_lock<std::mutex> lock(_cvm); ++ _tasks; lock.unlock(); _io_service.post( [this, f = std::forward<F>(f)] { f(); reduce(); }); } 11111111 es simplemente un miembro del template <class F> void submit( F&& f) { std::unique_lock<std::mutex> lock(_cvm); ++ _tasks; lock.unlock(); _io_service.post( [this, f = std::forward<F>(f)] { f(); reduce(); }); } 2 :

  template <class F> void submit( F&& f) {     std::unique_lock<std::mutex> lock(_cvm);     ++ _tasks;     lock.unlock();     _io_service.post(     [this, f = std::forward<F>(f)]                      {                          f();                          reduce();                      }); } 3  
  1. ¿Qué estoy haciendo mal?
  2. ¿Cómo puedo hacerlo usando STD :: BIND o BOOST :: BINT En lugar de usar un lambda?

PS: El código en http://ideone.com/g38z4h es mi esqueleto para G ++ (que obras). La http://ideone.com/d7nkop guardado como template <class F> void submit( F&& f) { std::unique_lock<std::mutex> lock(_cvm); ++ _tasks; lock.unlock(); _io_service.post( [this, f = std::forward<F>(f)] { f(); reduce(); }); } 4 también muestra el problema .

template <class F> void submit( F&& f) { std::unique_lock<std::mutex> lock(_cvm); ++ _tasks; lock.unlock(); _io_service.post( [this, f = std::forward<F>(f)] { f(); reduce(); }); } 5

Original en ingles

This question relates to this previous question.

I've implemented the code published there by Richard Hodges. The code published works for me when I use g++ (Debian 4.8.4-1) 4.8.4.

However, the implementation is part of a CUDA library, and I am stuck with CUDA 6.5 which unofficially supported C++11 features.

When I use the code Richard posted:

template <class F> void submit( F&& f) {     std::unique_lock<std::mutex> lock(_cvm);     ++ _tasks;     lock.unlock();     _io_service.post(     [this, f = std::forward<F>(f)]                      {                          f();                          reduce();                      }); } 

I get an error: error: expected a "]" referring to the lambda line. This makes me think that the header is not being parsed properly. I tried without the template, just passing a reference to my worker class, and without the forwarding.

void submit( trainer & job) {     std::unique_lock<std::mutex> lock(_cvm);     ++ _tasks;     lock.unlock();     _io_service.post([this,&]                      {                          job();                          reduce();                      }); } 

And I got error: an enclosing-function local variable cannot be referenced in a lambda body unless it is in the capture list.

So I explicitly added both this and job:

void submit( trainer & job) {     std::unique_lock<std::mutex> lock(_cvm);     ++ _tasks;     lock.unlock();     _io_service.post([this,&job]                      {                          job();                          reduce();                      }); } 

At which point, I got stuck at error:

error: could not convert xe2x80x98{{((cuANN::trainer_pool*)this)->cuANN::trainer_pool::_io_service}}xe2x80x99 from xe2x80x98<brace-enclosed initializer list>xe2x80x99 to xe2x80x98boost::asio::io_service::workxe2x80x99 boost::asio::io_service::work _work { _io_service };

FYI, cuANN::trainer_pool is the worker_pool in Richard's example, and the thread pool implementation, and _io_service is simply a member of the class trainer_pool:

class trainer_pool {    public:     trainer_pool ( unsigned int max_threads );     void start();     void wait();     void stop();      void thread_proc();     void reduce();     void submit( trainer & job);  private:     unsigned int _max_threads_;     boost::asio::io_service _io_service;     boost::asio::io_service::work _work { _io_service };     std::vector<std::thread> _threads;     std::condition_variable _cv;     std::mutex _cvm;     size_t _tasks = 0; }; 
  1. What am I doing wrong?
  2. How can I do it using std::bind or boost::bind instead of using a lambda?

PS: the code on http://ideone.com/g38Z4H is my skeleton for g++ (which works). The http://ideone.com/d7Nkop saved as host.cu also showcases the issue.

nvcc -std=c++11 host.cu -lboost_thread -lboost_system -lpthread -o host

              
         
         

Lista de respuestas

2
 
vote

Esta construcción:

  [this, f = std::forward<F>(f)]   

es C ++ 14 y no se compilará en C ++ 11.

Uso de =0 sería un error ya que no hay garantía de que el objeto de función aún exista (lo capturó como referencia)

en C ++ 11 Considere =1111 para tomar una copia.

Editar: Acabo de darme cuenta de que el trabajo es mutable, por lo tanto:

  =2  
 

this construct:

[this, f = std::forward<F>(f)] 

is c++14 and won't compile in c++11.

using [this, &] would be a mistake since there's no guarantee that the function object will still exist (you captured it by reference)

in c++11 consider [this, f] to take a copy.

edit: just realised that job is mutable, therefore:

void submit(trainer & job) {     std::unique_lock<std::mutex> lock(_cvm);     ++ _tasks;     lock.unlock();     _io_service.post([this,job]()->void mutable                      {                          job();                          reduce();                      }); } 
 
 
         
         
1
 
vote
vote
La mejor respuesta
 

Encontré el problema. NVCC y CUDA funcionan bien con los lambdas.

La línea ofensiva fue en el encabezado:

  =3  

CUDA 6.5 no le gusta la lista de inicializadores. Moviéndolo al constructor:

  =4  

parece haber solucionado el error y el código ahora compila. Muchas gracias a todos los que ayudaban.

 

I found the problem. NVCC and CUDA works fine with the lambdas.

The offending line was in the header:

boost::asio::io_service::work _work { _io_service }; 

CUDA 6.5 does not like the initializer list. Moving it to the constructor:

trainer_pool (unsigned int max_threads) :_max_threads_(max_threads), _work(_io_service) {} 

Seems to have fixed the error and the code now compiles. Many thanks to all who helped.

 
 

Relacionados problema

5  Dimensiones de bloques en CUDA  ( Block dimensions in cuda ) 
Tengo una capacidad de cómputo 2.0 de NVIDIA GTX 570 CUDA-4.0. El ejecutable de ViceQuery en el CUDA SDK me da información sobre mi dispositivo CUDA y sus d...

1  Proyecto de procesamiento distribuido "principiante"  ( Beginner distributed processing project ) 
Para el tiempo más largo, he estado interesado en construir un grupo de nodos heterogéneos en un intento por tener una supercomputadora doméstica ya que estoy...

1  Proyecto de CUDA simple NetBeans Litemon  ( Simple cuda project netbeans linking issue ) 
Cuando no esté comprobado habilitar la verificación de dependencias en NetBeans IDE (consulte este problema ) Ahora IDE usa NVCC y compila mi. Cu a .o, pero ...

0  Valor de threadidx.x (.y, .z), blockidx.x, etc. en CUDA  ( Value of threadidx x y z blockidx x etc in cuda ) 
Entiendo que uso threadidx.x, etc. para hacer referencia a un hilo específico, pero estoy transfiriendo el código de A para el bucle en una CPU y me gustaría ...

7  ¿Cómo realizar una copia profunda de la estructura con CUDA? [duplicar]  ( How to perform deep copying of struct with cuda ) 
Esta pregunta ya tiene respuestas aquí : Copia de una estructura que contiene punteros al dispositiv...

0  Detalles de la memoria global  ( Global memory details ) 
Esta es una pregunta de seguimiento para CUDA Memoria global, ¿dónde está? en referencia a la respuesta de Gsmith. Estos Q's Dirigir el CC & GT; 2.0 caso. ...

4  CUDA con Optimus solo para acceder a GPGPU  ( Cuda with optimus just to access gpgpu ) 
Tengo un Dell XPS L502 con la tarjeta gráfica NVIDIA 525M. Solo estoy interesado en usar las capacidades GPGPU de la tarjeta por ahora. Instalé Ubuntu 12.04...

13  Creando matrices en NVIDIA CUDA KERNEL  ( Creating arrays in nvidia cuda kernel ) 
Hola, solo quería saber si es posible hacer lo siguiente dentro del NVIDIA CUDA KERNEL __global__ void compute(long *c1, long size, ...) { ... long d[1...

11  Raytracing con CUDA  ( Raytracing with cuda ) 
Actualmente estoy implementando un RayTracer. Dado que Raytracing es extremadamente calculador pesado y, como lo voy a buscar en la programación de Cudá, me p...

7  Cómo generar, compilar y ejecutar Kernels CUDA en tiempo de ejecución  ( How to generate compile and run cuda kernels at runtime ) 
Bueno, tengo una pregunta bastante delicada :) Vamos a empezar con lo que tengo: Datos , gran variedad de datos, copiados a la GPU programa , generad...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos