Exemplos | Raio Deus | Documentação |
---|
Thrust é a biblioteca de algoritmos paralelos C++ que inspirou a introdução de algoritmos paralelos na Biblioteca Padrão C++. A interface de alto nível do Thrust aumenta muito a produtividade do programador, ao mesmo tempo que permite portabilidade de desempenho entre GPUs e CPUs multicore. Ele se baseia em estruturas de programação paralela estabelecidas (como CUDA, TBB e OpenMP). Ele também fornece vários recursos de uso geral semelhantes aos encontrados na Biblioteca Padrão C++.
A Biblioteca Padrão NVIDIA C++ é um projeto de código aberto; ele está disponível no GitHub e incluído no NVIDIA HPC SDK e no CUDA Toolkit. Se você tiver um desses SDKs instalados, nenhuma instalação adicional ou sinalizadores de compilador serão necessários para usar o libcu++.
O impulso é melhor aprendido por meio de exemplos.
O exemplo a seguir gera números aleatórios em série e depois os transfere para um dispositivo paralelo onde são classificados.
# 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 ());
}
Veja no Godbolt
Este exemplo demonstra o cálculo da soma de alguns números aleatórios em 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 >());
}
Veja no Godbolt
Este exemplo mostra como realizar tal redução de forma assíncrona:
# 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 >());
}
Veja no Godbolt
Thrust é uma biblioteca somente de cabeçalho; não há necessidade de compilar ou instalar o projeto, a menos que você queira executar os testes de unidade Thrust.
O CUDA Toolkit fornece uma versão recente do código-fonte do Thrust em include/thrust
. Isso será adequado para a maioria dos usuários.
Os usuários que desejam contribuir com o Thrust ou experimentar recursos mais recentes devem clonar recursivamente o repositório Thrust Github:
git clone --recursive https://github.com/NVIDIA/thrust.git
Para projetos baseados em CMake, fornecemos um pacote CMake para uso com find_package
. Consulte o README do CMake para obter mais informações. O Thrust também pode ser adicionado por meio de add_subdirectory
ou ferramentas como o CMake Package Manager.
Para projetos não CMake, compile com:
-I<thrust repo root>
)-I<thrust repo root>/dependencies/libcudacxx/
)-I<thrust repo root>/dependencies/cub/
)-DTHRUST_HOST_SYSTEM=THRUST_HOST_SYSTEM_XXX
, onde XXX
é CPP
(serial, padrão), OMP
(OpenMP) ou TBB
(Intel TBB)-DTHRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_XXX
, onde XXX
é CPP
, OMP
, TBB
ou CUDA
(padrão). Thrust usa o sistema de construção CMake para construir testes de unidade, exemplos e testes de cabeçalho. Para construir o Thrust como desenvolvedor, é recomendado que você use nosso sistema de desenvolvimento em contêiner:
# 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
Isso equivale ao seguinte, mas em um ambiente limpo em contêiner que possui todas as dependências 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
Por padrão, um sistema host CPP
serial, um sistema de dispositivo acelerado CUDA
e o padrão C++14 são usados. Isso pode ser alterado no CMake e por meio de sinalizadores para ci/local/build.bash
Mais informações sobre como configurar sua construção do Thrust e criar uma solicitação pull podem ser encontradas na seção de contribuições.
Thrust é um projeto de código aberto desenvolvido no GitHub. O Thrust é distribuído sob a licença Apache v2.0 com exceções LLVM; algumas partes são distribuídas sob a Licença Apache v2.0 e a Licença Boost v1.0.