将int转换为浮动

时间:2015-11-08 21:22:50

标签: opencl

我无法在任何地方找到任何有关我遇到的信息。我在一台带有ATI Radeon HD 6770M的iMac上为OpenCL中的Kohonen SOM编写了一些代码。我正在为上下文选择GPU设备。我的代码中有一行导致CL_DEVICE_NOT_AVAILABLE错误。如果我对它进行评论,那么代码编译得很好......但是有了它,以及我尝试过的变化,我总是得到错误。

以下是代码,其中有违规行注释:

  

" //仅此行,导致CL_DEVICE_NOT_AVAILABLE !!!"。

我希望你们其中一个人在某个时候碰到这个,因为我有点困惑。 convert_float(diff)对我不起作用。

肯定存在计算错误,因为我还没有超越基本的完整编译步骤,所以请随意忽略或指出这些错误。不管怎样,我真的只是试图超越编译。

inline float _calc_sample_distance(__global float* weights, ulong startIdx, uint nodeWidth, __constant float* sample) {
    float accum = 0.0f;
    float diff = 0.0f;
    uint i = 0;
    for(i = 0; i<nodeWidth; i++) {
        diff = weights[startIdx+i] - sample[i];
        accum += pow(diff,2);
    }
    accum = pow(accum, .5f);
    return accum;
}

inline void _calc_coords(uint dimCount, __constant uint* dimSizes, size_t offset, uint* thisCoords) {
    // reversed so, processed as xy, then y
    ulong trim = offset, multi = 0;
    int i = 0, j = 0;
    for(i = dimCount-1; i>=0; i--) {
        multi = 1;
        for(j=i-1; j>=0; j--) {
            multi *= dimSizes[j];
        }
        thisCoords[i] = trim / multi;
        trim = trim % multi; 
    } 
}

inline float _calc_map_coord_distance(uint dimCount, __constant uint* bmuCoords, uint* thisCoords) {
    float accum = 0.0f;
    uint i = 0;
    int diff = 0;
    for(i = 0; i < dimCount; i++) {
        diff = bmuCoords[i] - thisCoords[i];
        diff *= diff; 
        accum += (float)diff; // THIS line, only, causes CL_DEVICE_NOT_AVAILABLE !!!
    }
    accum = pow(accum,.5f);
    return accum;
}

__kernel void calc_kohonen_som_distances(
        // map data
        __global float* weights,      // weights
        uint nodeWidth,               // the number of weights per node
        uint nodeCount,               // the total number of weights
        __constant float* sample,     // sample, of nodeWidth wide
        __global float* output        // the output distance of each node to the sample
    ) {
    size_t nodeIndex = get_global_id(0);
    ulong startIdx = nodeIndex * nodeWidth;
    output[nodeIndex] = _calc_sample_distance(weights,startIdx,nodeWidth,sample);
}

__kernel void calc_kohonen_som_update_weights(
        // map data
        __global float* weights,       // weights
        uint nodeWidth,                // the number of weights per node
        uint dimCount,                 // the number of dimensions
        __constant uint* dimSizes,     // the size of each dimension
        __constant float *sampleData,  // the sample to use for updating the bmu and surrounding units
        __constant uint* bmuCoords,    // the coordinates of the best matching unit, from which we derive offset
        float learningRate,            // calculated on the CPU as per step
        float radius                   // calculated on the CPU as per step
    ) {
    size_t nodeIndex = get_global_id(0);
    ulong startIdx = nodeIndex * nodeWidth;

    uint* thisCoords = (uint*)malloc(sizeof(uint)*dimCount);
    memset(thisCoords,0,sizeof(uint)*dimCount);

    // determine the coordinates of the offset provided
    if(dimCount!=1) {
        _calc_coords(dimCount,dimSizes,nodeIndex,thisCoords);
    } else {
        thisCoords[0] = nodeIndex;
    }

    float distance = _calc_map_coord_distance(dimCount, bmuCoords, thisCoords);
    if(distance<radius) {
        float influence = exp( (-1*distance)/(2*pow(radius,2.0f)) );
        for(uint i=0;i<dimCount;i++) {
            weights[startIdx+i] = weights[startIdx+i] + ( influence * learningRate * (sampleData[i] - weights[startIdx+i]) );
        }
    }
}    

0 个答案:

没有答案