OpenCL неопределенное поведение в параллельном алгоритме редукции

Я работаю над простым параллельным алгоритмом сокращения, чтобы найти минимальное значение в массиве, и нахожу в своем алгоритме интересное неопределенное поведение. Я запускаю Intel OpenCL 1.2 на Ubuntu 16.04.

Следующее ядро-это то, что я пытаюсь запустить, которое в настоящее время дает мне неправильный ответ:

__kernel void Find_Min(int arraySize, __global double* scratch_arr, __global double* value_arr, __global double* min_arr){

    const int index = get_global_id(0);
    int length = (int)sqrt((double)arraySize);
    int start = index*length;
    double min_val = INFINITY;
    for(int i=start; i<start+length && i < arraySize; i++){
        if(value_arr[i] < min_val)
            min_val = value_arr[i];
    }
    scratch_arr[index] = min_val;

    barrier(CLK_GLOBAL_MEM_FENCE);
    if(index == 0){
        double totalMin = min_val;
        for(int i=1; i<length; i++){
            if(scratch_arr[i] < totalMin)
                totalMin = scratch_arr[i];
        }
        min_arr[0] = totalMin;
    }
}

Когда в положить в массив, который {0,-1,-2,-3,-4,-5,-6,-7,-8} в итоге возвращается -2.

Здесь возникает неопределенное поведение. Когда я запускаю следующее ядро с инструкцией printf перед барьером, я получаю правильный ответ (-8):

__kernel void Find_Min(int arraySize, __global double* scratch_arr, __global double* value_arr, __global double* min_arr){

    const int index = get_global_id(0);
    int length = (int)sqrt((double)arraySize);
    int start = index*length;
    double min_val = INFINITY;
    for(int i=start; i<start+length && i < arraySize; i++){
        if(value_arr[i] < min_val)
            min_val = value_arr[i];
    }
    scratch_arr[index] = min_val;
    printf("setting scratch[%i] to %fn", index, min_val);

    barrier(CLK_GLOBAL_MEM_FENCE);
    if(index == 0){
        double totalMin = min_val;
        for(int i=1; i<length; i++){
            if(scratch_arr[i] < totalMin)
                totalMin = scratch_arr[i];
        }
        min_arr[0] = totalMin;
    }
}

Единственное, что я могу думать, что это может произойти, это то, что я использую команду barrier неправильно, и все, что делает printf, вызывает задержку в ядре, которое каким-то образом синхронизирует вызовы, чтобы они все завершились до заключительного шага сокращения. Но без printf ядро 0 выполняет окончательное сокращение до завершения других ядер.

Есть ли у кого-либо еще какие-либо предложения или советы по отладке этой проблемы?

Заранее спасибо!!

1 ответ