2017-01-16 14 views
5

Obecnie badam boost_compute. Niestety jest mniej stron dokumentacji i przykładów, niż muszę zrozumieć, co robić.Jak wywołać funkcję zdefiniowaną przez funkcję boost_compute "BOOST_COMPUTE_FUNCTION"?

Biorąc pod uwagę następujący kod minified:

BOOST_COMPUTE_FUNCTION(bool, add, (int* values, int* results, int constant), 
{ 
    // Whats the indexing variable? 
    // In opencl it would be get_global_id(0) 
    int index = // ? 

    results[index] = values[index] + values[index + 1] + values[index + 2] + constant; 
}); 

void compute(float* results, compute::context* ctx, compute::command_queue* queue) 
{ 
    compute::vector<float> device_values(100, *ctx); 
    compute::vector<float> device_results(98, *ctx); 

    compute::copy(
     parameters->values.begin(), parameters->values.end(), device_values.begin(), *queue 
    ); 

    // Actual computation 
    // HOW TO CALL 'add' for every device_results element? 

    compute::copy(
     device_results.begin(), device_results.end(), results, *queue 
    ); 
} 

Jak wywołać funkcję „dodaj” i co to jest zmienna iteracji wewnątrz tej funkcji? Ponadto potrzebuję tej struktury kodu do bardziej złożonych obliczeń.

poważaniem Toni

+0

Wykorzystanie 'obliczeniowej :: transform', jak w tym przykładzie: http://www.boost.org/doc/libs/1_63_0/libs/compute/doc/html/boost_compute/advanced_topics.html# boost_compute.advanced_topics.custom_functions – ddemidov

+0

Funkcja w boost :: compute jest stosowana do pojedynczego elementu wektorowego. Prawdopodobnie szukasz niestandardowego jądra. – ddemidov

+0

Niestety nie mogę sobie wyobrazić wywołania transformacji we właściwy sposób. Przykład nie odpowiada na żadne pytanie:/ – infotoni91

Odpowiedz

1

w skrócie boost:compute funkcje są nieOpenCL funkcje jądra. Są bardziej podobne do funkcji jądra OpenGL.

Uważam, że twoja funkcja pobiera zbyt wiele parametrów do użycia z algorytmami boost:compute.
jednak nieco prostsze funkcji, po prostu dodając sąsiednie wartości bez stała, byłoby:

BOOST_COMPUTE_FUNCTION(boost::compute::float_, add, 
         (boost::compute::float_ values0, boost::compute::float_ values1), 
{ 
    return values0 + values1; 
}); 

I można nazwać użyciem boost::compute::transform jak @ddemidov zasugerował:

boost::compute::transform(values.begin(), values.end() -1, // values0 
          values.begin() +1, // values1 
          results.begin(), // results 
          add, queue); 

może być możliwe zaimplementuj swoją funkcję za pomocą funkcji boost::compute::lambda. np:

using namespace boost::compute::lambda; 

float c = 1.234; // some constant 

boost::compute::transform(values.begin(), values.end() -1, // values0 
          values.begin() +1, // values1 
          results.begin(), // results 
          _1 + _2 + c, queue); 

Ale to wciąż brakuje zbioru wartości ...

Twoja funkcja może być napisany jako jądro OpenCL w boost:compute pomocą BOOST_COMPUTE_STRINGIZE_SOURCE makro:

const char kernel_function_source[] = BOOST_COMPUTE_STRINGIZE_SOURCE(

    kernel void add(global float* values, global float* results, global float* constant) 
    { 
    size_t index = get_global_id(0); 
    results[index] = values[index] + values[index + 1] + values[index + 2] + *constant; 
    } 

); 

Po ciebie Zbudowałeś swój program jądra i utworzyłeś jądro (używając boost::compute::program), możesz ustawić argumenty jądra indywidualnie i zadzwonić do funkcji boost::compute::command_queueenqueue_1d_range_kernel:

kernel.set_arg(0, values.get_buffer()); 
kernel.set_arg(1, results.get_buffer()); 
kernel.set_arg(2, &constant); 
queue.enqueue_1d_range_kernel(kernel, 0, count, 0); 
+0

Dziękuję bardzo! Niestety, wywołanie 'clCreateKernel' w kernel.hpp powoduje, że puste jądro rzuca wyjątek. Zwykły OpenCL działa jednak jak urok. – infotoni91

Powiązane problemy