Пример #1
0
BT::ReturnStatus BT::ActionTestNode::Tick()
{

    int i = 0;
    while (get_status() != BT::HALTED && i++ < time_)
    {
        DEBUG_STDOUT(" Action " << get_name() << "running! Thread id:" << std::this_thread::get_id());
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    if (get_status() != BT::HALTED)
    {
        if (boolean_value_)
        {
            DEBUG_STDOUT(" Action " << get_name() << " Done!");
            return BT::SUCCESS;
        }
        else
        {
            DEBUG_STDOUT(" Action " << get_name() << " FAILED!");
            return BT::FAILURE;
        }
    }
    else
    {
        return BT::HALTED;
    }
}
Пример #2
0
void Execute(BT::ControlNode* root, int TickPeriod_milliseconds)
{
    std::cout << "Start Drawing!" << std::endl;
    // Starts in another thread the drawing of the BT
    std::thread t2(&drawTree, root);
    t2.detach();
    BT::DotBt dotbt(root);
    std::thread t(&BT::DotBt::publish, dotbt);

    root->ResetColorState();

    while (ros::ok())
    {
        DEBUG_STDOUT("Ticking the root node !");

        // Ticking the root node
        root->Tick();
        // Printing its state
        // root->GetNodeState();

        if (root->get_status() != BT::RUNNING)
        {
            // when the root returns a status it resets the colors of the tree
            root->ResetColorState();
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(TickPeriod_milliseconds));
    }
}
Пример #3
0
static void SynthProc(WM_MESSAGE* pMsg)
{
	int x;
	int NCode,Id;
	ProcessCommComponent(pMsg, &hCOMPcomm);
	switch (pMsg->MsgId)
	{
	case WM_CREATE:
		SynthCreateItems(pMsg->hWin);
		hCurSynthStringPanel = 0;
		break;
	case WM_DELETE:
		SynthDeleteItems();
		break;
	case WM_PAINT:
		GUI_SetBkColor(GUI_BLACK);
		GUI_Clear();
		GUI_SetTextMode(GUI_TEXTMODE_TRANS);
		GUI_DrawBitmap(&bmEMPTYTITLEBAR, 0, 0);
		GUI_SetFont(&GUI_Font32B_ASCII);
		x = WM_GetWindowSizeX(pMsg->hWin);
		{
			std::string title("Synth / MIDI");
			GUI_DispStringHCenterAt(GetTitleWithPreset(title).c_str(), x / 2, 5);
		}
		//PaintSynthCombo();
		break;
	case WM_NOTIFY_PARENT:
		if(DispatchCommComponent(pMsg,&hCOMPcomm))
		{
			Id = WM_GetId(pMsg->hWinSrc);
			NCode = pMsg->Data.v;
			switch(NCode)
			{
			case WM_NOTIFICATION_ADDVOICE:
				switch(Id)
				{
				case SYNTH_ID_STRINGPANEL1:
					SynthInsertVoice(0,0);
					break;
				case SYNTH_ID_STRINGPANEL2:
					SynthInsertVoice(1,0);
					break;
				case SYNTH_ID_STRINGPANEL3:
					SynthInsertVoice(2,0);
					break;
				case SYNTH_ID_STRINGPANEL4:
					SynthInsertVoice(3,0);
					break;
				case SYNTH_ID_STRINGPANEL5:
					SynthInsertVoice(4,0);
					break;
				case SYNTH_ID_STRINGPANEL6:
					SynthInsertVoice(5,0);
					break;
				}
				hCurSynthStringPanel = pMsg->hWinSrc;
				UpdateSynthSettingEx(MISAMODULE_SYNTH);
				UpdateVoiceInfo((PVOICE_INFO)MisaSynthString_GetVoice(hCurSynthStringPanel,MisaSynthString_GetVoiceIndex(hCurSynthStringPanel)));
				TopVoiceScreen(pMsg->hWin);
				break;
			case WM_NOTIFICATION_CLICKED:
				DEBUG_STDOUT("SYNTH button clicked!");
				break;
			case WM_NOTIFICATION_RELEASED:
				switch(Id)
				{
				case SYNTH_ID_MIDICTRL:
					TopControlAssignmentsScreen(pMsg->hWin);
					break;
				case SYNTH_ID_STRINGPANEL1:
				case SYNTH_ID_STRINGPANEL2:
				case SYNTH_ID_STRINGPANEL3:
				case SYNTH_ID_STRINGPANEL4:
				case SYNTH_ID_STRINGPANEL5:
				case SYNTH_ID_STRINGPANEL6:
					hCurSynthStringPanel = pMsg->hWinSrc;
					//UpdateSynthSettingEx(MISAMODULE_SYNTH);
					UpdateVoiceInfo((PVOICE_INFO)MisaSynthString_GetVoice(hCurSynthStringPanel,MisaSynthString_GetVoiceIndex(hCurSynthStringPanel)));
					TopVoiceScreen(pMsg->hWin);
					break;
				case CTL_NONE_ID:
				case CTL_TOUCH_X_ID:
				case CTL_TOUCH_Y_ID:
				case CTL_DRAG_X_ID:
				case CTL_DRAG_Y_ID:
				case CTL_BALL_X_ID:
				case CTL_BALL_Y_ID:
				case CTL_VARIATION_ID:
					break;
				default:
					;
				}
				DEBUG_STDOUT("SYNTH button released!");
				break;
			case WM_NOTIFICATION_VALUE_CHANGED:
				SynthTurnNotesOff();
				switch(Id)
				{
				case SYNTH_ID_STRINGPANEL1:
					SynthTuning(0,MisaSynthString_GetTune(pMsg->hWinSrc));
					break;
				case SYNTH_ID_STRINGPANEL2:
					SynthTuning(1,MisaSynthString_GetTune(pMsg->hWinSrc));
					break;
				case SYNTH_ID_STRINGPANEL3:
					SynthTuning(2,MisaSynthString_GetTune(pMsg->hWinSrc));
					break;
				case SYNTH_ID_STRINGPANEL4:
					SynthTuning(3,MisaSynthString_GetTune(pMsg->hWinSrc));
					break;
				case SYNTH_ID_STRINGPANEL5:
					SynthTuning(4,MisaSynthString_GetTune(pMsg->hWinSrc));
					break;
				case SYNTH_ID_STRINGPANEL6:
					SynthTuning(5,MisaSynthString_GetTune(pMsg->hWinSrc));
					break;
				default:
					;
				}
				break;
			case WM_NOTIFICATION_SEL_CHANGED:
				switch(Id)
				{
				case SYNTH_ID_STRINGPANEL1:
					SynthSetMidiOutChannel(0,MisaSynthString_GetChannel(pMsg->hWinSrc));
					break;
				case SYNTH_ID_STRINGPANEL2:
					SynthSetMidiOutChannel(1,MisaSynthString_GetChannel(pMsg->hWinSrc));
					break;
				case SYNTH_ID_STRINGPANEL3:
					SynthSetMidiOutChannel(2,MisaSynthString_GetChannel(pMsg->hWinSrc));
					break;
				case SYNTH_ID_STRINGPANEL4:
					SynthSetMidiOutChannel(3,MisaSynthString_GetChannel(pMsg->hWinSrc));
					break;
				case SYNTH_ID_STRINGPANEL5:
					SynthSetMidiOutChannel(4,MisaSynthString_GetChannel(pMsg->hWinSrc));
					break;
				case SYNTH_ID_STRINGPANEL6:
					SynthSetMidiOutChannel(5,MisaSynthString_GetChannel(pMsg->hWinSrc));
					break;
				default:
					;
				}
				break;
			case WM_NOTIFICATION_STRINGPANEL_SYNTH:
				switch(Id)
				{
				case SYNTH_ID_STRINGPANEL1:
					SynthSetMidiOutChannel(0,-1);
					break;
				case SYNTH_ID_STRINGPANEL2:
					SynthSetMidiOutChannel(1,-1);
					break;
				case SYNTH_ID_STRINGPANEL3:
					SynthSetMidiOutChannel(2,-1);
					break;
				case SYNTH_ID_STRINGPANEL4:
					SynthSetMidiOutChannel(3,-1);
					break;
				case SYNTH_ID_STRINGPANEL5:
					SynthSetMidiOutChannel(4,-1);
					break;
				case SYNTH_ID_STRINGPANEL6:
					SynthSetMidiOutChannel(5,-1);
					break;
				default:
					;
				}
				break;
			}
		}
		break;
	case WM_TOUCH:
		break;
	default:
		WM_DefaultProc(pMsg);
	}
}
Пример #4
0
static void DistortionProc(WM_MESSAGE* pMsg)
{
	int x, y;
	int NCode,Id;
	ProcessCommComponent(pMsg, &hCOMPcomm);
	switch (pMsg->MsgId)
	{
	case WM_CREATE:
		DistortionCreateItems(pMsg->hWin);
		break;
	case WM_DELETE:
		DistortionDeleteItems();
		break;
	case WM_PAINT:
		GUI_SetBkColor(GUI_BLACK);
		GUI_Clear();
		GUI_SetTextMode(GUI_TEXTMODE_TRANS);
		GUI_DrawBitmap(&bmEMPTYTITLEBAR, 0, 0);
		x = 222;
		y = bmEMPTYTITLEBAR.YSize;
		GUI_DrawBitmap(&bmDISTYPEAREA, x, y);
		GUI_SetFont(&GUI_Font32B_ASCII);
		x = WM_GetWindowSizeX(pMsg->hWin);
		{
			std::string title("Distortion");
			GUI_DispStringHCenterAt(GetTitleWithPreset(title).c_str(), x / 2, 5);
		}
		y += 20;
		GUI_DispStringHCenterAt(strDistype[disIndex], x / 2, y);
		break;
	case WM_NOTIFY_PARENT:
		if(DispatchCommComponent(pMsg,&hCOMPcomm))
		{
			Id = WM_GetId(pMsg->hWinSrc);
			NCode = pMsg->Data.v;
			switch(NCode)
			{
			case WM_NOTIFICATION_CLICKED:
				DEBUG_STDOUT("Distortion button clicked!");
				break;
			case WM_NOTIFICATION_RELEASED:
				switch(Id)
				{
				case DISTORTION_ID_LEFTARROW:
					--disIndex;
					if(0>disIndex)
					{
						disIndex = sizeof(strDistype)/4-1;
					}
					WM_InvalidateRect(pMsg->hWin, &rectDisType);
					DistortionSetType(DistortionGetFX(),disIndex);
					break;
				case DISTORTION_ID_RIGHTARROW:
					++disIndex;
					if(sizeof(strDistype)/4 <= disIndex)
					{
						disIndex = 0;
					}
					WM_InvalidateRect(pMsg->hWin, &rectDisType);
					DistortionSetType(DistortionGetFX(),disIndex);
					break;
				case COMMON_ID_CHECKON:
					DistortionOn(DistortionGetFX(), MisaCheckbox_GetStatus(hCOMPcomm.hCheckOn)?true:false);
					break;
				case COMMON_ID_FX1:
				case COMMON_ID_FX2:
				case COMMON_ID_CLOSE:
					UpdateSynthSettingEx(MISAMODULE_DISTORTION);
					break;
				case CTL_NONE_ID:
				case CTL_TOUCH_X_ID:
				case CTL_TOUCH_Y_ID:
				case CTL_DRAG_X_ID:
				case CTL_DRAG_Y_ID:
				case CTL_BALL_X_ID:
				case CTL_BALL_Y_ID:
				case CTL_VARIATION_ID:
					DistortionControlMenuProc(Id);
					break;
#if 0
				case DISTORTION_ID_PROGDRIVE:
					x = MisaProgressbar_GetPercent(pMsg->hWinSrc);
					DistortionSetDrive(DistortionGetFX(),x<127?x:127);
					break;
				case DISTORTION_ID_PROGTONE:
					x = MisaProgressbar_GetPercent(pMsg->hWinSrc);
					DistortionSetTone(DistortionGetFX(),x<127?x:127);
					break;
				case DISTORTION_ID_PROGLEVEL:
					x = MisaProgressbar_GetPercent(pMsg->hWinSrc);
					DistortionSetLevel(DistortionGetFX(),x<127?x:127);
					break;
#endif
				default:
					;
				}
				DEBUG_STDOUT("Distortion button released!");
				break;
			case WM_NOTIFICATION_VALUE_CHANGED:
				switch(Id)
				{
				case DISTORTION_ID_PROGDRIVE:
					x = MisaProgressbar_GetPercent(pMsg->hWinSrc);
					DistortionSetDrive(DistortionGetFX(),x<127?x:127);
					break;
				case DISTORTION_ID_PROGTONE:
					x = MisaProgressbar_GetPercent(pMsg->hWinSrc);
					DistortionSetTone(DistortionGetFX(),x<127?x:127);
					break;
				case DISTORTION_ID_PROGLEVEL:
					x = MisaProgressbar_GetPercent(pMsg->hWinSrc);
					DistortionSetLevel(DistortionGetFX(),x<127?x:127);
					break;
				case DISTORTION_ID_PROGNOISEREDUCTION:
					x = MisaProgressbar_GetPercent(pMsg->hWinSrc);
					DistortionNoiseReduction(DistortionGetFX(),x);
					break;
				case DISTORTION_ID_PROGBOOSTER:
					x = MisaProgressbar_GetPercent(pMsg->hWinSrc);
					DistortionSetBooster(DistortionGetFX(),x<127?x/32:3);
					break;
				default:
					;
				}
				break;
			case WM_NOTIFICATION_SEL_CHANGED:
				if(hDistortionItems[DISTORTION_PROGNOISEREDUCTION]!=pMsg->hWinSrc && hDistortionItems[DISTORTION_PROGBOOSTER]!=pMsg->hWinSrc)
				{
					std::vector<int> effect;
					x = WM_GetWindowOrgX(pMsg->hWinSrc)+50;
					y = WM_GetWindowOrgY(pMsg->hWinSrc)+340;
					MisaSetcontrolmenu_Popup(pMsg->hWin,pMsg->hWinSrc,x,y);
					effect = SynthFindEffect(SynthTranslateEffect(Id),DistortionGetFX());
					y = effect.size();
					for(x=0;x<y;x++)
					{
						if(-1 != effect[x])
						{
							MisaMenu_SetStatus(AssigneMentMenuTranslate(effect[x]&0x000000FF),2,0,(effect[x]>>8)&0x000000FF);
							MisaMenu_SetStatus(CTL_VARMIN,0,(effect[x]>>16)&0x000000FF,(effect[x]>>8)&0x000000FF);
							MisaMenu_SetStatus(CTL_VARMAX,0,(effect[x]>>24)&0x000000FF,(effect[x]>>8)&0x000000FF);
						}
					}
				}
				break;
			}
BT::ReturnStatus BT::SequenceNodeWithMemory::Tick()
{
    DEBUG_STDOUT(get_name() << " ticked, memory counter: "<< current_child_idx_);

    // Vector size initialization. N_of_children_ could change at runtime if you edit the tree
    N_of_children_ = children_nodes_.size();

    // Routing the ticks according to the sequence node's (with memory) logic:
    while (current_child_idx_ < N_of_children_)
    {
        /*      Ticking an action is different from ticking a condition. An action executed some portion of code in another thread.
                We want this thread detached so we can cancel its execution (when the action no longer receive ticks).
                Hence we cannot just call the method Tick() from the action as doing so will block the execution of the tree.
                For this reason if a child of this node is an action, then we send the tick using the tick engine. Otherwise we call the method Tick() and wait for the response.
        */

        if (children_nodes_[current_child_idx_]->get_type() == BT::ACTION_NODE)
        {
            // 1) If the child i is an action, read its state.
            // Action nodes runs in another thread, hence you cannot retrieve the status just by executing it.

            child_i_status_ = children_nodes_[current_child_idx_]->get_status();
            DEBUG_STDOUT(get_name() << " It is an action " << children_nodes_[current_child_idx_]->get_name()
                         << " with status: " << child_i_status_);

            if (child_i_status_ == BT::IDLE || child_i_status_ == BT::HALTED)
            {
                // 1.1) If the action status is not running, the sequence node sends a tick to it.
                DEBUG_STDOUT(get_name() << "NEEDS TO TICK " << children_nodes_[current_child_idx_]->get_name());
                children_nodes_[current_child_idx_]->tick_engine.Tick();

                // waits for the tick to arrive to the child
                do
                {
                    child_i_status_ = children_nodes_[current_child_idx_]->get_status();
                    std::this_thread::sleep_for(std::chrono::milliseconds(10));
                }
                while (child_i_status_ != BT::RUNNING && child_i_status_ != BT::SUCCESS
                       && child_i_status_ != BT::FAILURE);
            }
        }
        else
        {
            // 2) if it's not an action:
            // Send the tick and wait for the response;
            child_i_status_ = children_nodes_[current_child_idx_]->Tick();
        }

        if (child_i_status_ == BT::SUCCESS ||child_i_status_ == BT::FAILURE )
        {
             // the child goes in idle if it has returned success or failure.
            children_nodes_[current_child_idx_]->set_status(BT::IDLE);
        }

        if (child_i_status_ != BT::SUCCESS)
        {
            // If the  child status is not success, return the status
            DEBUG_STDOUT("the status of: " << get_name() << " becomes " << child_i_status_);
            if (child_i_status_ == BT::FAILURE && (reset_policy_ == BT::ON_FAILURE
                                                   || reset_policy_ == BT::ON_SUCCESS_OR_FAILURE))
            {
                current_child_idx_ = 0;
            }
            set_status(child_i_status_);
            return child_i_status_;
        }
        else if (current_child_idx_ != N_of_children_ - 1)
        {
            // If the  child status is success, continue to the next child
            // (if any, hence if(current_child_ != N_of_children_ - 1) ) in the for loop (if any).
            current_child_idx_++;
        }
        else
        {
            // if it the last child.
            if (child_i_status_ == BT::SUCCESS)
            {
                // if it the last child and it has returned SUCCESS, reset the memory
                current_child_idx_ = 0;
            }
            set_status(child_i_status_);
            return child_i_status_;
        }
    }
    return BT::EXIT;
}
Пример #6
0
BT::ReturnStatus BT::SequenceNode::Tick()
{
    // gets the number of children. The number could change if, at runtime, one edits the tree.
    N_of_children_ = children_nodes_.size();

    // Routing the ticks according to the sequence node's logic:

    for (unsigned int i = 0; i < N_of_children_; i++)
    {
        /*      Ticking an action is different from ticking a condition. An action executed some portion of code in another thread.
                We want this thread detached so we can cancel its execution (when the action no longer receive ticks).
                Hence we cannot just call the method Tick() from the action as doing so will block the execution of the tree.
                For this reason if a child of this node is an action, then we send the tick using the tick engine. Otherwise we call the method Tick() and wait for the response.
        */
        if (children_nodes_[i]->get_type() == BT::ACTION_NODE)
        {
            // 1) If the child i is an action, read its state.
            child_i_status_ = children_nodes_[i]->get_status();

            if (child_i_status_ == BT::IDLE || child_i_status_ == BT::HALTED)
            {
                // 1.1) If the action status is not running, the sequence node sends a tick to it.
                DEBUG_STDOUT(get_name() << "NEEDS TO TICK " << children_nodes_[i]->get_name());
                children_nodes_[i]->tick_engine.Tick();

                // waits for the tick to arrive to the child
                do
                {
                    child_i_status_ = children_nodes_[i]->get_status();
                    std::this_thread::sleep_for(std::chrono::milliseconds(10));
                }
                while (child_i_status_ != BT::RUNNING && child_i_status_ != BT::SUCCESS
                       && child_i_status_ != BT::FAILURE);
            }
        }
        else
        {
            // 2) if it's not an action:
            // Send the tick and wait for the response;
            child_i_status_ = children_nodes_[i]->Tick();
        }
        // Ponderate on which status to send to the parent
        if (child_i_status_ != BT::SUCCESS)
        {
            // If the  child status is not success, halt the next children and return the status to your parent.
            if (child_i_status_ == BT::FAILURE)
            {
                children_nodes_[i]->set_status(BT::IDLE);  // the child goes in idle if it has returned failure.
            }

            DEBUG_STDOUT(get_name() << " is HALTING children from " << (i+1));
            HaltChildren(i+1);
            set_status(child_i_status_);
            return child_i_status_;
        }
        else
        {
            // the child returned success.
            children_nodes_[i]->set_status(BT::IDLE);

            if (i == N_of_children_ - 1)
            {
                // If the  child status is success, and it is the last child to be ticked,
                // then the sequence has succeeded.
                set_status(BT::SUCCESS);
                return BT::SUCCESS;
            }
        }
    }
    return BT::EXIT;
}
Пример #7
0
void BT::ActionTestNode::Halt()
{
    set_status(BT::HALTED);
    DEBUG_STDOUT("HALTED state set!");
}
Пример #8
0
int Parallel::setup() {
    /**
     * OpenCL initialization.
     */
    cl_int status = Simulator::setup();
    CheckStatus(status, "Simulator::setup() failed.");
    
    cl_uint numPlatforms;
    status = clGetPlatformIDs(0, NULL, &numPlatforms);
    CheckStatus(status, "clGetPlatformIDs, fetching number");
    DEBUG_STDOUT("Number of platforms: " << numPlatforms);
    
    cl_platform_id platform = NULL;
    if (numPlatforms > 0) {
        std::unique_ptr<cl_platform_id[]> platforms (new cl_platform_id[numPlatforms]);
        status = clGetPlatformIDs(numPlatforms, platforms.get(), NULL);
        CheckStatus(status, "clGetPlatformIDs, fetching platforms");
        
        for (unsigned i = 0; i < numPlatforms; ++i) {
            char pbuf[100];
            status = clGetPlatformInfo(platforms[i],
                                       CL_PLATFORM_VENDOR,
                                       sizeof(pbuf),
                                       pbuf,
                                       NULL);
            CheckStatus(status, "clGetPlatformInfo");
        }
        
        // Just grab the first platform.
        platform = platforms[0];
    }
    CheckConditional(platform != NULL, "platform == NULL");
    
    cl_uint numDevices;
    status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, 0, NULL, &numDevices);
    CheckStatus(status, "clGetDeviceIDs: fetching number");
    DEBUG_STDOUT("Number of devices: " << numDevices);
    
    cl_device_id *devices = new cl_device_id[numDevices];
    status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, numDevices, devices, NULL);
    CheckStatus(status, "clGetDeviceIDs: fetching devices");
    
    int deviceIndex = 0;
    for (unsigned i = 0; i < numDevices; ++i) {
        char pbuf[100];
        status = clGetDeviceInfo(devices[i],
                                 CL_DEVICE_NAME,
                                 sizeof(pbuf),
                                 pbuf,
                                 NULL);
        if (!strncmp(pbuf, "ATI", 3)) {
            deviceIndex = i;
        }
    }
    
    /* Create the context. */
    context = clCreateContext(0, numDevices, devices, NULL, NULL, &status);
    CheckConditional(context != NULL, "clCreateContextFromType");
    
    /* Create command queue */
    cl_command_queue_properties prop = CL_QUEUE_PROFILING_ENABLE;
    commandQueue = clCreateCommandQueue(context, devices[deviceIndex], prop, &status);
    CheckStatus(status, "clCreateCommandQueue");
    
    /* Create a CL program using the kernel source */
    SDKFile kernelFile;
    std::string kernelPath = getenv("HOME") + std::string("/md-simulator/src/TestKernel.cl");
    if(!kernelFile.open(kernelPath.c_str())) {
        DEBUG_STDERR("Failed to load kernel file : " << kernelPath);
        return MD_FAILURE;
    }
    
    const char *source = kernelFile.source().c_str();
    size_t sourceSize[] = {strlen(source)};
    program = clCreateProgramWithSource(context,
                                        1,
                                        &source,
                                        sourceSize,
                                        &status);
    CheckStatus(status, "clCreateProgramWithSource");
    
    /* Create a cl program executable for all the devices specified */
    status = clBuildProgram(program,
                            numDevices,
                            devices,
                            NULL,
                            NULL,
                            NULL);
    
    if (status != CL_SUCCESS) {
        if (status == CL_BUILD_PROGRAM_FAILURE) {
            cl_int logStatus;
            std::unique_ptr<char[]> buildLog (nullptr);
            //char *buildLog = NULL;
            size_t buildLogSize = 0;
            logStatus = clGetProgramBuildInfo(program,
                                              devices[deviceIndex],
                                              CL_PROGRAM_BUILD_LOG,
                                              buildLogSize,
                                              buildLog.get(),
                                              &buildLogSize);
            CheckStatus(logStatus, "clGetProgramBuildInfo");
            
            buildLog = std::unique_ptr<char[]>(new char[buildLogSize]);
            if(!buildLog) {
                return MD_FAILURE;
            }
            std::fill_n(buildLog.get(), buildLogSize, 0);
            
            logStatus = clGetProgramBuildInfo(program,
                                              devices[deviceIndex],
                                              CL_PROGRAM_BUILD_LOG,
                                              buildLogSize,
                                              buildLog.get(),
                                              NULL);
            CheckStatus(logStatus, "clGetProgramBuildInfo (2)");
            
            DEBUG_STDERR("\n\t\t\tBUILD LOG\n");
            DEBUG_STDERR("************************************************\n");
            DEBUG_STDERR(buildLog.get());
            DEBUG_STDERR("************************************************\n");
        }
    }
    CheckStatus(status, "clBuildProgram");
    
    /* Get a kernel object handle for a kernel with the given name */
    kernel = clCreateKernel(program, "computeAccelerations", &status);
    CheckStatus(status, "clCreateKernel");
    
    /* Check group size against group size returned by kernel */
    status = clGetKernelWorkGroupInfo(kernel,
                                      devices[deviceIndex],
                                      CL_KERNEL_WORK_GROUP_SIZE,
                                      sizeof(size_t),
                                      &kernelWorkGroupSize,
                                      0);
    CheckStatus(status, "clGetKernelWorkGroupInfo");
    DEBUG_STDOUT("kernelWorkGroupSize: " << kernelWorkGroupSize);
    
    /**
     * Initialize some simulator data structures.
     */
    global = particleCount * particleCount;
    local = particleCount;
    
    if (global * local > kernelWorkGroupSize) {
        DEBUG_STDERR("WARNING - global * local > kernelWorkGroupSize; global: " << global << ", local: " << local << ", kernelWorkGroupSize: " << kernelWorkGroupSize);
        return MD_FAILURE;
    }
    
    // Data holds the molecule positions.
    data = std::unique_ptr<float[]> (new float[particleCount * 3]);
    
    // Constants holds simulator constants.
    constants = std::unique_ptr<float[]> (new float[NUM_CONSTANTS]);
    
    // Copy constants to buffer;
    constants[0] = epsilon;
    constants[1] = sigma;
    constants[2] = negForceCutoffMinusHalf;
    constants[3] = forceCutoffMinusHalf;
    constants[4] = wallStiffness;
    
    // Results holds pairwise forces.
    results = std::unique_ptr<float[]> (new float[particleCount * particleCount * 3]);
    
    return MD_SUCCESS;
}