Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] View of /branches/vis12-cl/src/compiler/cl-target/fragments/c-init.in
ViewVC logotype

View of /branches/vis12-cl/src/compiler/cl-target/fragments/c-init.in

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3124 - (download) (annotate)
Tue Mar 24 09:59:45 2015 UTC (5 years, 8 months ago) by jhr
File size: 6848 byte(s)
  Working on getting OpenCL version right
#ifdef USE_CALLBACK
/*! callback to log OpenCL error messages */
static void LogMessages (const char *errstr, const void *pvtInfo, size_t cb, void *userData)
{
    @PREFIX@World_t *wrld = (@PREFIX@World_t *)userData;
    biffMsgAddf (
        wrld->errors,
        "***** error log *****\n"       \
        "%s\n"                          \
        "***** end error log *****\n", errstr); 
}
#endif

/*! initialize the OpenCL execution context, including loading and compiling the OpenCL
 *    program.
 *  \param wrld the Diderot execution information.
 *  \return true if there is an error, otherwise false.
 */
static bool InitCL (@PREFIX@World_t *wrld)
{
    cl_int              sts;
    Diderot_OCLInfo_t   *oclInfo = wrld->oclInfo;
    Diderot_DeviceInfo_t *dev = wrld->device;

    if (dev != 0) {
      // use the user supplied device if it is an available GPU
        if ((! Diderot_isGPUDevice (dev)) || (! dev->isAvail)) {
            biffMsgAddf (wrld->errors,
                "specified OpenCL device %d.%d is not a GPU or is not available\n",
		dev->index[0], dev->index[1]);
            return true;
        }
    }
    else {
	int pltIx = 0;  // main patform index
	int devID;
      // find a GPU on platform[0]
        for (int i = 0;  i < oclInfo->platforms[pltIx].numDevices;  i++) {
            if (Diderot_isGPUDevice (&(oclInfo->platforms[pltIx].devices[i]))
            &&  oclInfo->platforms[pltIx].devices[i].isAvail) {
                devID = i;
                dev = &(oclInfo->platforms[pltIx].devices[i]);
                break;
            }
        }
        if (dev == 0) {
            biffMsgAddf (wrld->errors, "unable to find GPU device\n");
            return true;
        }
	wrld->device = dev;
    }

    if (wrld->verboseFlg) {
        fprintf (stderr, "using platform %d, device %d: %s\n",
            dev->index[0], dev->index[1], dev->name);
    }

  // create the context; we pass the world as user data so that we can record errors
  // in the errors biff
#ifdef USE_CALLBACK
    cl_context cxt = clCreateContext(0, 1, &(dev->id), LogMessages, wrld, &sts);
#else
    cl_context cxt = clCreateContext(0, 1, &(dev->id), 0, 0, &sts);
#endif
    if (sts != CL_SUCCESS) {
        biffMsgAddf (wrld->errors, "error creating OpenCL context\n");
        return true;
    }

  // create the program from the source
    int fnameLen = strlen(wrld->name) + 4;  // name + ".cl\0"
    char *fname = (char *)CheckedAlloc(fnameLen);
    snprintf(fname, fnameLen, "%s.cl", wrld->name);
    cl_program prog = Diderot_LoadProgramFromSource ((WorldPrefix_t *)wrld, cxt, fname, &sts);
    free (fname);
    if (sts != CL_SUCCESS) {
        biffMsgAddf (wrld->errors, "error creating program\n");
        return true;
    }

  // build the program
    char options[1024];
    snprintf (options, sizeof(options),
        "-cl-std=@CL_STD@ -D DIDEROT_CU_WIDTH=%d -I %s -w",
        dev->cuWidth,
        DIDEROT_INCLUDE_PATH);
    if (wrld->verboseFlg) {
        fprintf (stderr, "clBuildProgram options: %s\n", options);
    }
    sts = clBuildProgram (prog, 1, &(dev->id), options, 0, 0);
    if (sts != CL_SUCCESS) {
      /* this is a likely a bug in the Diderot compiler, which has produced incorrect OpenCL
       * code, so we report the error directly to stderr.
       */
        size_t logSzb;
        clGetProgramBuildInfo (prog, dev->id, CL_PROGRAM_BUILD_LOG, 0, 0, &logSzb);
        char *log = CheckedAlloc(logSzb+1);
        clGetProgramBuildInfo (prog, dev->id, CL_PROGRAM_BUILD_LOG, logSzb, log, &logSzb);
        log[logSzb] = '\0';
/*
        biffMsgAddf (wrld->errors, "error compiling program:\n%s\n", log);
*/
        fprintf (stderr, "error compiling program:\n%s\n", log);
        free (log);
        return true;
    }

  // create the command queue
    cl_command_queue q = clCreateCommandQueue(cxt, dev->id, 0, &sts);
    if (sts != CL_SUCCESS) {
        biffMsgAddf (wrld->errors, "error creating OpenCL command queue\n");
        return true;
    }

  // initialize world info
    wrld->context = cxt;
    wrld->cmdQ = q;
    wrld->prog = prog;

  // bind kernels
    if (BindKernels (wrld)) {
        biffMsgAddf (wrld->errors, "error binding kernels\n");
        return true;
    }

    return false;
}

// Allocate the program's world
//
@PREFIX@World_t *@PREFIX@New ()
{
    @PREFIX@World_t *wrld = NEW(@PREFIX@World_t);
    if (wrld == 0)
        return 0;

    wrld->name          = ProgramName;
    wrld->errors        = biffMsgNew("DIDEROT");

    if (wrld->errors == 0) {
        free (wrld);
        return 0;
    }

    wrld->stage         = POST_NEW;
    wrld->verboseFlg    = false;
    wrld->nStrandTys    = 1;  /* FIXME */
/*
    wrld->strandDesc    = &Strand_@STRAND@;
*/
    wrld->runTime	= 0.0;

  // get information about OpenCL support
    wrld->oclInfo = Diderot_GetCLInfo((WorldPrefix_t *)wrld);
    if (wrld->oclInfo == 0) {
        return 0;
    }

    wrld->device        = 0;
    wrld->gpuDevId      = -1;

    return wrld;

}

//! Initialize the program's world; returns true on error.
//
bool @PREFIX@Init (@PREFIX@World_t *wrld)
{
    if (wrld->stage != POST_NEW) {
        biffMsgAdd (wrld->errors, "multiple calls to @PREFIX@Init");
        return true;
    }

  // initialize the OpenCL context, etc.
    if (InitCL(wrld)) {
        return true;
    }

    cl_int sts;

  // get the sizes of GPU-side data structures
    cl_mem clSizes = clCreateBuffer(wrld->context, CL_MEM_WRITE_ONLY, sizeof(Diderot_Sizes_t), 0, &sts);
    if (CheckOCLStatus(wrld, sts, "unable to allocate GPU memory"))
        return true;
    sts = clSetKernelArg(wrld->GetSizesKern, 0, sizeof(cl_mem), &clSizes);
    if (CheckOCLStatus(wrld, sts, "error setting arguments for sizes kernel"))
        return true;
    sts = clEnqueueTask(wrld->cmdQ, wrld->GetSizesKern, 0, NULL, NULL);
    if (CheckOCLStatus(wrld, sts, "error enqueuing sizes kernel"))
        return true;
    sts = clEnqueueReadBuffer(wrld->cmdQ, clSizes, CL_TRUE, 0, sizeof(Diderot_Sizes_t), &(wrld->oclSizes), 0, 0, 0);
    if (CheckOCLStatus(wrld, sts, "error getting sizes"))
        return true;

  // allocate memory for the device-side globals structure
    wrld->globalsBuf = clCreateBuffer (wrld->context, CL_MEM_READ_WRITE, wrld->oclSizes.globSzB, 0, &sts);
    if (CheckOCLStatus(wrld, sts, "error creating OpenCL globals memory buffer"))
        return true;

  // allocate memory for the device-side scheduler structure
    wrld->schedBuf = clCreateBuffer (wrld->context, CL_MEM_READ_WRITE, wrld->oclSizes.schedSzB, 0, &sts);
    if (CheckOCLStatus(wrld, sts, "error creating OpenCL scheduler memory buffer"))
        return true;

#ifndef DIDEROT_STANDALONE_EXEC
  // initialize the defined flags for the input globals
    @PREFIX@InitDefined (wrld);
#endif

    wrld->stage = POST_INIT;

    return false;

}

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0