Ejemplos | rayo divino | Documentación |
---|
Thrust es la biblioteca de algoritmos paralelos de C++ que inspiró la introducción de algoritmos paralelos en la biblioteca estándar de C++. La interfaz de alto nivel de Thrust mejora enormemente la productividad del programador al tiempo que permite la portabilidad del rendimiento entre GPU y CPU multinúcleo. Se basa en marcos de programación paralelos establecidos (como CUDA, TBB y OpenMP). También proporciona una serie de funciones de uso general similares a las que se encuentran en la biblioteca estándar de C++.
La biblioteca estándar NVIDIA C++ es un proyecto de código abierto; está disponible en GitHub y se incluye en NVIDIA HPC SDK y CUDA Toolkit. Si tiene uno de esos SDK instalado, no se necesita instalación adicional ni indicadores del compilador para usar libcu++.
El empuje se aprende mejor a través de ejemplos.
El siguiente ejemplo genera números aleatorios en serie y luego los transfiere a un dispositivo paralelo donde se ordenan.
# include < thrust/host_vector.h >
# include < thrust/device_vector.h >
# include < thrust/generate.h >
# include < thrust/sort.h >
# include < thrust/copy.h >
# include < thrust/random.h >
int main () {
// Generate 32M random numbers serially.
thrust::default_random_engine rng ( 1337 );
thrust::uniform_int_distribution< int > dist;
thrust::host_vector< int > h_vec ( 32 << 20 );
thrust::generate (h_vec. begin (), h_vec. end (), [&] { return dist (rng); });
// Transfer data to the device.
thrust::device_vector< int > d_vec = h_vec;
// Sort data on the device.
thrust::sort (d_vec. begin (), d_vec. end ());
// Transfer data back to host.
thrust::copy (d_vec. begin (), d_vec. end (), h_vec. begin ());
}
Véalo en Godbolt
Este ejemplo demuestra cómo calcular la suma de algunos números aleatorios en paralelo:
# include < thrust/host_vector.h >
# include < thrust/device_vector.h >
# include < thrust/generate.h >
# include < thrust/reduce.h >
# include < thrust/functional.h >
# include < thrust/random.h >
int main () {
// Generate random data serially.
thrust::default_random_engine rng ( 1337 );
thrust::uniform_real_distribution< double > dist (- 50.0 , 50.0 );
thrust::host_vector< double > h_vec ( 32 << 20 );
thrust::generate (h_vec. begin (), h_vec. end (), [&] { return dist (rng); });
// Transfer to device and compute the sum.
thrust::device_vector< double > d_vec = h_vec;
double x = thrust::reduce (d_vec. begin (), d_vec. end (), 0 , thrust::plus< int >());
}
Véalo en Godbolt
Este ejemplo muestra cómo realizar dicha reducción de forma asincrónica:
# include < thrust/host_vector.h >
# include < thrust/device_vector.h >
# include < thrust/generate.h >
# include < thrust/async/copy.h >
# include < thrust/async/reduce.h >
# include < thrust/functional.h >
# include < thrust/random.h >
# include < numeric >
int main () {
// Generate 32M random numbers serially.
thrust::default_random_engine rng ( 123456 );
thrust::uniform_real_distribution< double > dist (- 50.0 , 50.0 );
thrust::host_vector< double > h_vec ( 32 << 20 );
thrust::generate (h_vec. begin (), h_vec. end (), [&] { return dist (rng); });
// Asynchronously transfer to the device.
thrust::device_vector< double > d_vec (h_vec. size ());
thrust::device_event e = thrust::async::copy (h_vec. begin (), h_vec. end (),
d_vec. begin ());
// After the transfer completes, asynchronously compute the sum on the device.
thrust::device_future< double > f0 = thrust::async::reduce (thrust::device. after (e),
d_vec. begin (), d_vec. end (),
0.0 , thrust::plus< double >());
// While the sum is being computed on the device, compute the sum serially on
// the host.
double f1 = std::accumulate (h_vec. begin (), h_vec. end (), 0.0 , thrust::plus< double >());
}
Véalo en Godbolt
Thrust es una biblioteca de solo encabezados; No es necesario compilar ni instalar el proyecto a menos que desee ejecutar las pruebas unitarias de Thrust.
El kit de herramientas CUDA proporciona una versión reciente del código fuente de Thrust en include/thrust
. Esto será adecuado para la mayoría de los usuarios.
Los usuarios que deseen contribuir a Thrust o probar funciones más nuevas deben clonar recursivamente el repositorio de Thrust Github:
git clone --recursive https://github.com/NVIDIA/thrust.git
Para proyectos basados en CMake, proporcionamos un paquete CMake para usar con find_package
. Consulte el archivo README de CMake para obtener más información. Thrust también se puede agregar a través de add_subdirectory
o herramientas como CMake Package Manager.
Para proyectos que no sean CMake, compile con:
-I<thrust repo root>
)-I<thrust repo root>/dependencies/libcudacxx/
)-I<thrust repo root>/dependencies/cub/
)-DTHRUST_HOST_SYSTEM=THRUST_HOST_SYSTEM_XXX
, donde XXX
es CPP
(serie, predeterminado), OMP
(OpenMP) o TBB
(Intel TBB)-DTHRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_XXX
, donde XXX
es CPP
, OMP
, TBB
o CUDA
(predeterminado). Thrust utiliza el sistema de compilación CMake para crear pruebas unitarias, ejemplos y pruebas de encabezado. Para construir Thrust como desarrollador, se recomienda que utilice nuestro sistema de desarrollo en contenedores:
# Clone Thrust and CUB repos recursively:
git clone --recursive https://github.com/NVIDIA/thrust.git
cd thrust
# Build and run tests and examples:
ci/local/build.bash
Eso hace el equivalente a lo siguiente, pero en un entorno contenedorizado limpio que tiene todas las dependencias instaladas:
# Clone Thrust and CUB repos recursively:
git clone --recursive https://github.com/NVIDIA/thrust.git
cd thrust
# Create build directory:
mkdir build
cd build
# Configure -- use one of the following:
cmake .. # Command line interface.
ccmake .. # ncurses GUI (Linux only).
cmake-gui # Graphical UI, set source/build directories in the app.
# Build:
cmake --build . -j ${NUM_JOBS} # Invokes make (or ninja, etc).
# Run tests and examples:
ctest
De forma predeterminada, se utilizan un sistema host CPP
en serie, un sistema de dispositivo acelerado CUDA
y el estándar C++14. Esto se puede cambiar en CMake y mediante indicadores a ci/local/build.bash
Puede encontrar más información sobre cómo configurar su compilación Thrust y crear una solicitud de extracción en la sección de contribuciones.
Thrust es un proyecto de código abierto desarrollado en GitHub. Thrust se distribuye bajo la licencia Apache v2.0 con excepciones LLVM; Algunas partes se distribuyen bajo la licencia Apache v2.0 y la licencia Boost v1.0.