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 2733 - (download) (annotate)
Thu Sep 25 19:50:05 2014 UTC (5 years ago) by jhr
File size: 6003 byte(s)
  working on OpenCL support
/*! 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, int devID)
{
    cl_int              sts;
    int                 pltIx = 0;  // main patform index
    DeviceInfo_t        *dev = 0;
    CLInfo_t		*oclInfo = wrld->oclInfo;

    if ((0 <= devID) && (devID < oclInfo->platforms[pltIx].numDevices)) {
      // use the user supplied device
        if (isGPUDevice (&(oclInfo->platforms[pltIx].devices[devID]))
        &&  oclInfo->platforms[pltIx].devices[devID].isAvail) {
            dev = &(oclInfo->platforms[pltIx].devices[devID]);
        }
        else {
            biffMsgAddf (wrld->errors,
		"specified OpenCL device %d is not a GPU or is not available\n", devID);
            return true;
        }
    }
    else {
      // find a GPU on platform[0]
        for (int i = 0;  i < oclInfo->platforms[pltIx].numDevices;  i++) {
            if (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;
        }
    }

    if (wrld->verboseFlg) {
        fprintf (stderr, "using platform %d, device %d: %s\n",
            pltIx, devID, dev->name);
    }

  // create the context
    cl_context cxt = clCreateContext(0, 1, &(dev->id), LogMessagesToStderr, 0, &sts);
    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);
    char *updateSource = LoadSource (fname);
    free (fname);

    const char *src[1] = {updateSource};
    cl_program prog = clCreateProgramWithSource(cxt, 1, src, NULL, &sts);
    free (updateSource);
    if (sts != CL_SUCCESS) {
        biffMsgAddf (wrld->errors, "error creating program\n");
        return true;
    }

  // build the program
    char options[1024];
    snprintf (options, sizeof(options),
        "-D DIDEROT_CL_VERSION=%d -D DIDEROT_CU_WIDTH=%d -I %s -w",
        100*dev->majorVersion + dev->minorVersion,
        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) {
        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);
        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->device = dev;
    wrld->context = cxt;
    wrld->cmdQ = q;

  // bind kernels
    /* FIXME */

    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->globals       = NEW(@PREFIX@Globals_t);

    if (wrld->globals == 0) {
	biffMsgNix (wrld->errors);
        FREE (wrld);
        return 0;
    }

    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;
    }

  // get information about OpenCL support
    wrld->oclInfo = GetCLInfo();
    if (wrld->oclInfo == 0) {
	biffMsgAdd (wrld->errors, "unable to get information about the OpenCL environment");
        return true;
    }

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

    cl_int sts;

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

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

/* FIXME: need to allocate scheduler data structures */

#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