Пример #1
0
bool ConvFilterBase::setFilterKernel(const float *filter, int size, int filter_w,
                                     QCLBuffer & filter_ocl,
                                     QCLKernel & kernel_ocl,
                                     int & filter_ocl_size)
{
  if (size != filter_ocl_size)
  {
    filter_ocl = m_ctx->createBufferCopy(filter, size * sizeof(float), QCLMemoryObject::ReadOnly);
    if (filter_ocl.isNull())
    {
      ERRORM("Failed to create convolution kernel buffer: " << m_ctx->lastError());
      return false;
    }

    filter_ocl_size = size;

    kernel_ocl.setArg(FILTER_IDX, filter_ocl);
    kernel_ocl.setArg(FILTER_SIZE_IDX, filter_w);
    kernel_ocl.setArg(FILTER_SIZE_HALF_IDX, (filter_w - 1) / 2);
  }
  else
  {
    if (!filter_ocl.write(filter, size * sizeof(float)))
    {
      ERRORM("Failed to write convolution kernel data: " << m_ctx->lastError());
      return false;
    }
  }

  return true;
}
Пример #2
0
int JacobiCL2(QVector< QVector<float> > A, int n, QCLContext *context, float *x, float eps)
{
    if(!context) {
        context = new QCLContext();

        if(!context->create(QCLDevice::GPU)) {
            qFatal("Could not create OpenCL context");
        }
    }

    float *A2 = new float[n*(n+1)];
    for(int i = 0; i < n; i++) {
        memcpy(&A2[i*(n+1)], A[i].data(), (n+1)*sizeof(float));
    }

    QCLProgram program;

    program = context->buildProgramFromSourceFile(QLatin1String("cl/jacobi.cl"));

    QCLKernel jacobi_pre2 = program.createKernel("jacobi_pre2");
    QCLKernel jacobi2 = program.createKernel("jacobi2");

    jacobi_pre2.setGlobalWorkSize(n, n);
    jacobi2.setGlobalWorkSize(n, 1);

    QCLBuffer buffA = context->createBufferDevice(n*(n+1)*sizeof(float), QCLMemoryObject::ReadWrite);
    QCLBuffer buffA2 = context->createBufferDevice(n*(n+1)*sizeof(float), QCLMemoryObject::ReadWrite);

    buffA.write(A2, n*(n+1)*sizeof(float));

    QCLVector<float> xcl = context->createVector<float>(n, QCLMemoryObject::ReadWrite);

    float *x2 = new float[n];

    memset(x, 0, n*sizeof(float));
    memset(x2, 0, n*sizeof(float));

    xcl.write(x, n);

    QTime t;
    t.start();

    int it = 0;
    float norm = 1;
    while(norm > eps)
    {
        memcpy(x2, x, n*sizeof(float));

        jacobi_pre2(buffA, buffA2, xcl, n).waitForFinished();
        jacobi2(buffA, buffA2, xcl, n).waitForFinished();

        xcl.read(x, n);
        norm = normMax(x, x2, n);

        qDebug() << "JCL2:"<< it++ << norm;
    }

    return t.elapsed();
}
Пример #3
0
int JacobiCL(QVector< QVector<float> > A, int n, QCLContext *context, float *x, float eps)
{
    if(!context) {
        context = new QCLContext();

        if(!context->create(QCLDevice::GPU)) {
            qFatal("Could not create OpenCL context");
        }
    }

    float *A2 = new float[n*(n+1)];
    for(int i = 0; i < n; i++) {
        memcpy(&A2[i*(n+1)], A[i].data(), (n+1)*sizeof(float));
    }

    QCLProgram program;

    program = context->buildProgramFromSourceFile(QLatin1String("cl/jacobi.cl"));

    QCLKernel jacobi_pre = program.createKernel("jacobi_pre");
    QCLKernel jacobi = program.createKernel("jacobi");

    jacobi_pre.setGlobalWorkSize(n, n);
    jacobi.setGlobalWorkSize(n, 1);

    QCLBuffer buffA = context->createBufferDevice(n*(n+1)*sizeof(float), QCLMemoryObject::ReadWrite);

    QCLVector<float> xcl = context->createVector<float>(n, QCLMemoryObject::ReadWrite);

    float *x2 = new float[n];

    memset(x, 0, n*sizeof(float));
    memset(x2, 0, n*sizeof(float));

    xcl.write(x, n);

    QTime t;
    t.start();

    int it = 0;
    float norm = 1;
    while(norm > eps)
    {
        buffA.write(A2, n*(n+1)*sizeof(float)); // Необходимо на каждой итерации перезаписывать матрицу исходной, т.к. она модифицируется в процессе вычислений
        memcpy(x2, x, n*sizeof(float));

        jacobi_pre(buffA, xcl, n).waitForFinished();
        jacobi(buffA, xcl, n).waitForFinished();

        xcl.read(x, n);
        norm = normMax(x, x2, n);

        qDebug() << "JCL:"<< it++ << norm;
    }

    return t.elapsed();
}
Пример #4
0
/*!
    Copies the contents of \a rect within this buffer to \a dest,
    starting at \a destPoint.  The source and destination line pitch
    values are given by \a bufferBytesPerLine and \a destBytesPerLine
    respectively.

    The request will not start until all of the events in \a after
    have been signaled as finished.  The request is executed on
    the active command queue for context().

    This function is only supported in OpenCL 1.1 and higher.

    \sa copyToRect()
*/
QCLEvent QCLBuffer::copyToRectAsync
(const QRect &rect, const QCLBuffer &dest, const QPoint &destPoint,
 size_t bufferBytesPerLine, size_t destBytesPerLine,
 const QCLEventList &after)
{
#ifdef QT_OPENCL_1_1
    const size_t src_origin[3] = {rect.x(), rect.y(), 0};
    const size_t dst_origin[3] = {destPoint.x(), destPoint.y(), 0};
    const size_t region[3] = {rect.width(), rect.height(), 1};
    cl_event event;
    cl_int error = clEnqueueCopyBufferRect
                   (context()->activeQueue(), memoryId(), dest.memoryId(),
                    src_origin, dst_origin, region,
                    bufferBytesPerLine, 0, destBytesPerLine, 0,
                    after.size(), after.eventData(), &event);
    context()->reportError("QCLBuffer::copyToRectAsync:", error);
    if (error == CL_SUCCESS)
        return QCLEvent(event);
    else
        return QCLEvent();
#else
    context()->reportError("QCLBuffer::copyToRectAsync:", CL_INVALID_OPERATION);
    Q_UNUSED(rect);
    Q_UNUSED(dest);
    Q_UNUSED(destPoint);
    Q_UNUSED(bufferBytesPerLine);
    Q_UNUSED(destBytesPerLine);
    Q_UNUSED(after);
    return false;
#endif
}
Пример #5
0
/*!
    Copies the 3D rectangle defined by \a origin and \a size within
    this buffer to \a destOrigin within \a dest.  The source and destination
    pitch values are given by \a bufferBytesPerLine, \a bufferBytesPerSlice,
    \a destBytesPerLine, and \a destBytesPerSlice.

    The request will not start until all of the events in \a after
    have been signaled as finished.  The request is executed on
    the active command queue for context().

    This function is only supported in OpenCL 1.1 and higher.

    \sa copyToRectAsync()
*/
QCLEvent QCLBuffer::copyToRectAsync
(const size_t origin[3], const size_t size[3],
 const QCLBuffer &dest, const size_t destOrigin[3],
 size_t bufferBytesPerLine, size_t bufferBytesPerSlice,
 size_t destBytesPerLine, size_t destBytesPerSlice,
 const QCLEventList &after)
{
#ifdef QT_OPENCL_1_1
    cl_event event;
    cl_int error = clEnqueueCopyBufferRect
                   (context()->activeQueue(), memoryId(), dest.memoryId(),
                    origin, destOrigin, size,
                    bufferBytesPerLine, bufferBytesPerSlice,
                    destBytesPerLine, destBytesPerSlice,
                    after.size(), after.eventData(), &event);
    context()->reportError("QCLBuffer::copyToRectAsync(3D):", error);
    if (error == CL_SUCCESS)
        return QCLEvent(event);
    else
        return QCLEvent();
#else
    context()->reportError("QCLBuffer::copyToRectAsync(3D):", CL_INVALID_OPERATION);
    Q_UNUSED(origin);
    Q_UNUSED(size);
    Q_UNUSED(dest);
    Q_UNUSED(destOrigin);
    Q_UNUSED(bufferBytesPerLine);
    Q_UNUSED(bufferBytesPerSlice);
    Q_UNUSED(destBytesPerLine);
    Q_UNUSED(destBytesPerSlice);
    Q_UNUSED(after);
    return false;
#endif
}
Пример #6
0
/*!
    Copies the 3D rectangle defined by \a origin and \a size within
    this buffer to \a destOrigin within \a dest.  The source and destination
    pitch values are given by \a bufferBytesPerLine, \a bufferBytesPerSlice,
    \a destBytesPerLine, and \a destBytesPerSlice.  Returns true if
    the copy was successful; false otherwise.

    This function will block until the request finishes.
    The request is executed on the active command queue for context().

    This function is only supported in OpenCL 1.1 and higher.

    \sa copyToRectAsync()
*/
bool QCLBuffer::copyToRect
(const size_t origin[3], const size_t size[3],
 const QCLBuffer &dest, const size_t destOrigin[3],
 size_t bufferBytesPerLine, size_t bufferBytesPerSlice,
 size_t destBytesPerLine, size_t destBytesPerSlice)
{
#ifdef QT_OPENCL_1_1
    cl_event event;
    cl_int error = clEnqueueCopyBufferRect
                   (context()->activeQueue(), memoryId(), dest.memoryId(),
                    origin, destOrigin, size,
                    bufferBytesPerLine, bufferBytesPerSlice,
                    destBytesPerLine, destBytesPerSlice, 0, 0, &event);
    context()->reportError("QCLBuffer::copyToRect(3D):", error);
    if (error == CL_SUCCESS) {
        clWaitForEvents(1, &event);
        clReleaseEvent(event);
        return true;
    } else {
        return false;
    }
#else
    context()->reportError("QCLBuffer::copyToRect(3D):", CL_INVALID_OPERATION);
    Q_UNUSED(origin);
    Q_UNUSED(size);
    Q_UNUSED(dest);
    Q_UNUSED(destOrigin);
    Q_UNUSED(bufferBytesPerLine);
    Q_UNUSED(bufferBytesPerSlice);
    Q_UNUSED(destBytesPerLine);
    Q_UNUSED(destBytesPerSlice);
    return false;
#endif
}
Пример #7
0
/*!
    Copies the contents of \a rect within this buffer to \a dest,
    starting at \a destPoint.  The source and destination line pitch
    values are given by \a bufferBytesPerLine and \a destBytesPerLine
    respectively.  Returns true if the copy was successful; false otherwise.

    This function will block until the request finishes.
    The request is executed on the active command queue for context().

    This function is only supported in OpenCL 1.1 and higher.

    \sa copyToRectAsync()
*/
bool QCLBuffer::copyToRect
(const QRect &rect, const QCLBuffer &dest,
 const QPoint &destPoint, size_t bufferBytesPerLine,
 size_t destBytesPerLine)
{
#ifdef QT_OPENCL_1_1
    const size_t src_origin[3] = {rect.x(), rect.y(), 0};
    const size_t dst_origin[3] = {destPoint.x(), destPoint.y(), 0};
    const size_t region[3] = {rect.width(), rect.height(), 1};
    cl_event event;
    cl_int error = clEnqueueCopyBufferRect
                   (context()->activeQueue(), memoryId(), dest.memoryId(),
                    src_origin, dst_origin, region,
                    bufferBytesPerLine, 0, destBytesPerLine, 0, 0, 0, &event);
    context()->reportError("QCLBuffer::copyToRect:", error);
    if (error == CL_SUCCESS) {
        clWaitForEvents(1, &event);
        clReleaseEvent(event);
        return true;
    } else {
        return false;
    }
#else
    context()->reportError("QCLBuffer::copyToRect:", CL_INVALID_OPERATION);
    Q_UNUSED(rect);
    Q_UNUSED(dest);
    Q_UNUSED(destPoint);
    Q_UNUSED(bufferBytesPerLine);
    Q_UNUSED(destBytesPerLine);
    return false;
#endif
}
Пример #8
0
/*!
    Returns true if the OpenCL \a buffer object is also an OpenGL
    buffer object; false otherwise.
*/
bool QCLContextGL::isGLBuffer(const QCLBuffer &buffer)
{
#ifndef QT_NO_CL_OPENGL
    cl_gl_object_type objectType;
    if (clGetGLObjectInfo
            (buffer.memoryId(), &objectType, 0) != CL_SUCCESS)
        return false;
    return objectType == CL_GL_OBJECT_BUFFER;
#else
    Q_UNUSED(buffer);
    return false;
#endif
}
Пример #9
0
/*!
    Requests that the \a size bytes at \a offset in this buffer
    be copied to \a destOffset in the buffer \a dest.  Returns an
    event object that can be used to wait for the request to finish.

    The request will not start until all of the events in \a after
    have been signaled as finished.  The request is executed on
    the active command queue for context().

    \sa copyTo()
*/
QCLEvent QCLBuffer::copyToAsync
(size_t offset, size_t size, const QCLBuffer &dest, size_t destOffset,
 const QCLEventList &after)
{
    cl_event event;
    cl_int error = clEnqueueCopyBuffer
                   (context()->activeQueue(), memoryId(), dest.memoryId(),
                    offset, destOffset, size,
                    after.size(), after.eventData(), &event);
    context()->reportError("QCLBuffer::copyToAsync:", error);
    if (error != CL_SUCCESS)
        return QCLEvent();
    else
        return QCLEvent(event);
}
Пример #10
0
/*!
    Copies the \a size bytes at \a offset in this buffer
    be copied to \a destOffset in the buffer \a dest.  Returns true
    if the copy was successful; false otherwise.

    This function will block until the request finishes.
    The request is executed on the active command queue for context().

    \sa copyToAsync()
*/
bool QCLBuffer::copyTo
(size_t offset, size_t size, const QCLBuffer &dest, size_t destOffset)
{
    cl_event event;
    cl_int error = clEnqueueCopyBuffer
                   (context()->activeQueue(), memoryId(), dest.memoryId(),
                    offset, destOffset, size, 0, 0, &event);
    context()->reportError("QCLBuffer::copyTo(QCLBuffer):", error);
    if (error == CL_SUCCESS) {
        clWaitForEvents(1, &event);
        clReleaseEvent(event);
        return true;
    } else {
        return false;
    }
}