Exemple #1
0
int main(int argc, char **argv)
{
	srand((unsigned)time(NULL));

	Kernel kernel;
	CommandQueue queue;
	Context context;

	{
		std::vector<Platform> platformList;
		Platform::get(&platformList);

		clog << "Platform number is: " << platformList.size() << endl;

		std::string platformVendor;
		platformList[0].getInfo((cl_platform_info)CL_PLATFORM_VENDOR, &platformVendor);
		clog << "Platform is by: " << platformVendor << "\n";

		cl_context_properties cprops[] = {
			CL_CONTEXT_PLATFORM, (cl_context_properties) platformList[0](),
			0
		};
		context = Context(GET_TARGET_PLATFORM, cprops);

		std::vector<Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();
		queue = CommandQueue(context, devices[0]);

		std::string sourceCode = "#include \"es.cl\"\n";
		Program::Sources source(1, std::make_pair(sourceCode.c_str(), sourceCode.length()+1));
		Program program = Program(context, source);

		try
		{
			program.build(devices, "-I.");
		}
		catch (Error &)
		{
			std::string errors;
			program.getBuildInfo(devices[0], CL_PROGRAM_BUILD_LOG, &errors);
			std::cerr << "Build log: " << endl << errors << endl;
			return 1;
		}

		kernel = Kernel(program, "es");
	}

	individual *individuals = new individual[LAMBDA];
	for (int i = 0; i < LAMBDA; i++)
	{
		for (int j = 0; j < DIM; ++j)
		{
			individuals[i].x[j] = (rand()/((float)RAND_MAX)) * (XMAX-XMIN) + XMIN;
			individuals[i].s[j] = (XMAX-XMIN) / 6.f;
		}
		for (int j = 0; j < DIM_A; ++j)
		{
			individuals[i].a[j] = (rand()/((float)RAND_MAX)) * (2*PI) - PI;
		}
		
		individuals[i].fitness = 0;
	}

	float gbest = std::numeric_limits<float>::infinity(), xbest[DIM];
	
	Buffer esBuffer = Buffer(context, 0, INDIVIDUALS_SIZE);
	Event ev;
	queue.enqueueMapBuffer(esBuffer, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, 0, INDIVIDUALS_SIZE);
	
	for (int i = 0; i < 1000; i++)
	{
		queue.enqueueWriteBuffer(esBuffer, CL_TRUE, 0, INDIVIDUALS_SIZE, individuals);
		kernel.setArg(1, (cl_ulong)rand());
		kernel.setArg(0, esBuffer);
		queue.enqueueNDRangeKernel(kernel, NullRange, NDRange(LAMBDA), NDRange(1), NULL, &ev);
		ev.wait();
		queue.enqueueReadBuffer(esBuffer, CL_TRUE, 0, INDIVIDUALS_SIZE, individuals);
		
		std::sort(individuals, individuals + LAMBDA, individual_comp);
		individual mean = get_mean(individuals);
		for (int j = 0; j < LAMBDA; ++j)
		{
			individuals[j] = mean;
		}
	}
	gbest = individuals[0].fitness;
	for (int i = 0; i < DIM; ++i) xbest[i] = individuals[0].x[i];
	clog << "Best value " << gbest << " found at (";
	for (int i = 0; i < DIM; ++i) clog << xbest[i] << (i == DIM-1 ? ")" : ", ");
	clog << "\n";
	clog << "Our computation estemates it: f(" << xbest[0] << ", ..., " << xbest[DIM-1] << ") = " << es_f(xbest) << endl;

	delete[] individuals;

	return 0;
}
Exemple #2
0
/******************************************************************************
* main
******************************************************************************/
int main(int argc, char *argv[])
{
   /*-------------------------------------------------------------------------
   * Catch ctrl-c so we ensure that we call dtors and the dsp is reset properly
   *------------------------------------------------------------------------*/
   signal(SIGABRT, exit);
   signal(SIGTERM, exit);

   struct timespec tp_start, tp_end;

   try 
   {
     /*------------------------------------------------------------------------
     * One time OpenCL Setup
     *-----------------------------------------------------------------------*/
     Context             context(CL_DEVICE_TYPE_ALL); 
     std::vector<Device> devices(context.getInfo<CL_CONTEXT_DEVICES>());

     CommandQueue        *QcpuIO = NULL;
     CommandQueue        *QcpuOO = NULL;
     CommandQueue        *QdspOO = NULL;

     std::vector<Device> dspDevices;
     for (int d = 0; d < devices.size(); d++)
     {
	cl_device_type type;
	devices[d].getInfo(CL_DEVICE_TYPE, &type);

	if (type == CL_DEVICE_TYPE_CPU)
	{
	   QcpuIO = new CommandQueue(context, devices[d], PROFILE);
	   QcpuOO = new CommandQueue(context, devices[d], PROFILE|OOOEXEC);
	}
	else if (type == CL_DEVICE_TYPE_ACCELERATOR)
        {
	   QdspOO  = new CommandQueue(context, devices[d], PROFILE|OOOEXEC);
           dspDevices.push_back(devices[d]);
        }
     }

     if (QcpuIO == NULL)
     {
	std::cout << 
	"CPU devices are not fully supported in the current" << std::endl <<
	"OpenCL implementation (native kernel support only)." << std::endl << 
	"As a result, CPU devices are not enabled by" << std::endl <<
	"default.  This example uses OpenCL CPU native" << std::endl <<
	"kernels and can be run with the CPU device enabled." << std::endl << 
        "To enable a CPU device define the environment variable" << std::endl <<
        "'TI_OCL_CPU_DEVICE_ENABLE' before running the example." << std::endl;
	 exit(-1);
     }

     assert(QdspOO != NULL);

     Program::Sources    source (1, std::make_pair(kernStr, strlen(kernStr)));
     Program             program(Program(context, source));

     program.build(dspDevices);
     Kernel K(program, "compute");

     /*------------------------------------------------------------------------
     * Define a Buffer for each possible in flight task
     *-----------------------------------------------------------------------*/
     std::vector<BufUP> bufs;
     for (int i = 0; i < inflight; ++i) 
         bufs.push_back(BufUP(new Buffer(context, CL_MEM_READ_WRITE, size)));

     /*------------------------------------------------------------------------
     * Define a 3-D vector of OpenCL Events.  1st dim is for the number of 
     * in flight tasks, the second dim is for the processing stages of a single
     * task.  The 3rd dim is an artifact of the c++ binding for event wait 
     * lists.  All enqueue API's take a wait list which is a vector<Event>*, and
     * they take an Event*.  All events in the wait list vector must complete,
     * before this event will execute.  The single event argument is for the 
     * event that will be set as a result of this enqueue. 
     *-----------------------------------------------------------------------*/
     vecVecVecEv evt(inflight, vecVecEv(STAGES, vecEv(1)));

     /*------------------------------------------------------------------------
     * Enqueue a dummy DSP kernel call to force the OpenCL lazy execution
     * to go ahead and compile the kernel and load it.  This will prevent the 
     * compile and load times from skewing the reported numbers.  This is not 
     * needed by the algorithm and is purely a tactic to get consistent numbers
     * from the the running of the bulk of this algorithm
     *-----------------------------------------------------------------------*/
     K.setArg(0, *bufs[0]);
     K.setArg(1, 0);
     QdspOO->enqueueTask(K);

     K.setArg(1, elements);
     clock_gettime(CLOCK_MONOTONIC, &tp_start);

     /*------------------------------------------------------------------------
     * Iterate for as many tasks as there are
     *-----------------------------------------------------------------------*/
     for (int i = 0; i < tasks; ++i)
     {
        /*---------------------------------------------------------------------
        * Variables to ensure that this iteration is using the correct circular
        * resources: i.e. buffers and arrays.
        *--------------------------------------------------------------------*/
        int     circIdx = i % inflight;
        Buffer &buf(*bufs[circIdx]);
        int    *ary(arys [circIdx]);
        Event  nullEv;

        /*---------------------------------------------------------------------
        * Native kernels are only passed a single pointer, so define a structure
        * that contains the actual arguments, populate that and then create 
        * a C++ binding native argument class that has the pointer and a size.
        *--------------------------------------------------------------------*/
        arguments_t proArgs = { ary, elements, i,   i };
        arguments_t conArgs = { ary, elements, i+1, i };
        native_arg_t proNargs(&proArgs, sizeof(proArgs));
        native_arg_t conNargs(&conArgs, sizeof(conArgs));

        K.setArg(0, buf);

        /*---------------------------------------------------------------------
        * Since we are reusing N sets of buffers in this loop, we need to make
        * sure than iteration I does not start until after iteration I-N 
        * completes. Iterations < N can start immediately.
        *--------------------------------------------------------------------*/
        vecEv *start_waits = (i < inflight) ? 0 : &evt[circIdx][CNS];

        evt[circIdx][PRD][0] = nullEv;
        evt[circIdx][WRT][0] = nullEv;
        evt[circIdx][CMP][0] = nullEv;
        evt[circIdx][RD ][0] = nullEv;

        QcpuOO->enqueueNativeKernel(cpu_produce, proNargs, 0, 0,  
                start_waits,        &evt[circIdx][PRD][0]);

        evt[circIdx][CNS][0] = nullEv;

        QdspOO->enqueueWriteBuffer (buf, CL_FALSE, 0, size, ary,  
                &evt[circIdx][PRD], &evt[circIdx][WRT][0]);
        QdspOO->enqueueTask        (K,                            
                &evt[circIdx][WRT], &evt[circIdx][CMP][0]);
        QdspOO->enqueueReadBuffer  (buf, CL_FALSE, 0, size, ary,  
                &evt[circIdx][CMP], &evt[circIdx][RD ][0]);
        QcpuIO->enqueueNativeKernel(cpu_consume, conNargs, 0, 0,  
                &evt[circIdx][RD ], &evt[circIdx][CNS][0]);
     }

     /*------------------------------------------------------------------------
     * Only need to wait for the CPU In Order queue to finish, since all all
     * other enqueue events must finish before the CPU IO queue can finish
     *-----------------------------------------------------------------------*/
     QcpuIO->finish();

     delete QcpuIO;
     delete QcpuOO;
     delete QdspOO;

     clock_gettime(CLOCK_MONOTONIC, &tp_end);
     double elapsed = clock_diff (&tp_start, &tp_end);
     printf("Elapsed : %8.6f secs\n", elapsed);

     /*------------------------------------------------------------------------
     * After the running is complete, report timing for each step
     *-----------------------------------------------------------------------*/
#if PROFILE 
     cl_ulong ref;
     evt[0][0][0].getProfilingInfo(CL_PROFILING_COMMAND_QUEUED, &ref);

     for (int i = 0; i < inflight; ++i)
     {
          for (int s = 0; s < STAGES; ++s)
              ocl_relative_times(evt[i][s][0], stage_names[s], ref);
          cout << endl;
     }
#endif
   }

   catch (Error err)
   {
       cerr << "ERROR: " << err.what() << "("
            << ocl_decode_error(err.err()) << ")"
            << endl;
       incorrect_results = true;
   }

   if (incorrect_results) return -1;
}