static cl_int runIntegral(CLInfo* ci,
                          SeparationCLMem* cm,
                          RunSizes* runSizes,
                          EvaluationState* es,
                          const CLRequest* clr,
                          const AstronomyParameters* ap,
                          const IntegralArea* ia)
{
    cl_int err = CL_SUCCESS;
    double t1, t2, dt;
    double tAcc = 0.0;

    for (; es->nu_step < ia->nu_steps; es->nu_step++)
    {
        if (clr->enableCheckpointing && timeToCheckpointGPU(es, ia))
        {
            err = checkpointCL(ci, cm, ia, es);
            if (err != CL_SUCCESS)
                break;
        }

        t1 = mwGetTimeMilli();
        err = runNuStep(ci, ia, runSizes, es->nu_step);
        if (err != CL_SUCCESS)
        {
            mwPerrorCL(err, "Failed to run nu step");
            return err;
        }
        t2 = mwGetTimeMilli();

        dt = t2 - t1;
        tAcc += dt;

        reportProgress(ap, ia, es, es->nu_step + 1, dt);
    }

    es->nu_step = 0;

    mw_printf("Integration time: %f s. Average time per iteration = %f ms\n",
              tAcc / 1000.0, tAcc / (double) ia->nu_steps);

    if (err == CL_SUCCESS)
    {
        err = readKernelResults(ci, cm, es, ia);
        if (err != CL_SUCCESS)
            mw_printf("Failed to read final kernel results\n");

        /* Add final episode to running totals */
        addTmpCheckpointSums(es);
    }

    return err;
}
static CALresult runIntegral(const AstronomyParameters* ap,
                             const IntegralArea* ia,
                             EvaluationState* es,
                             const CLRequest* clr,
                             MWCALInfo* ci,
                             SeparationCALMem* cm)
{
    CALresult err;
    SeparationCALNames cn;
    double t1, t2, dt, tAcc = 0.0;
    SeparationCALChunks chunks;

    memset(&cn, 0, sizeof(SeparationCALNames));
    err = getModuleNames(ci, &cn, cm->numberStreams);
    if (err != CAL_RESULT_OK)
    {
        cal_warn("Failed to get module names", err);
        return err;
    }

    err = setKernelArguments(ci, cm, &cn);
    if (err != CAL_RESULT_OK)
    {
        destroyModuleNames(&cn);
        return err;
    }


    if (findCALChunks(ap, ci, clr, ia, &chunks) != CAL_RESULT_OK)
        return CAL_RESULT_ERROR;

    for (; es->nu_step < ia->nu_steps; es->nu_step++)
    {
        if (clr->enableCheckpointing && timeToCheckpointGPU(es, ia))
        {
            err = checkpointCAL(cm, ia, es);
            if (err != CAL_RESULT_OK)
                break;
        }

        t1 = mwGetTimeMilli();

        err = runNuStep(ci, cm, ia, &chunks, clr->pollingMode, es->nu_step);
        if (err != CAL_RESULT_OK)
            break;

        t2 = mwGetTimeMilli();
        dt = t2 - t1;
        tAcc += dt;

        reportProgress(ap, ia, es, es->nu_step + 1, dt);
    }
    es->nu_step = 0;

    warn("Integration time = %f s, average per iteration = %f ms\n", 1.0e-3 * tAcc, tAcc / ia->nu_steps);

    destroyModuleNames(&cn);
    freeCALChunks(&chunks);

    if (err == CAL_RESULT_OK)
    {
        readResults(cm, ia, es);
        addTmpSums(es); /* Add final episode to running totals */
    }

    return err;
}