Component unable to allocate device that is not Executable Device

756 Views Asked by At

I am using Redhawk 1.9. I create a Redhawk Device, Component, Node, and Waveform with default settings. I use C++ implementation on all the above. The problem is that the device can't be allocated since it is not an executable device. In the implementation tab in the code section the "type" variable is set to "Executable" (default value). If this is incorrect then what should it be?

Note: When I make an Device derived from executable device then the problem goes away.

I was able to reproduce the problem with dummy device and component as shown below: I update the Component so that it will use the device.

<usesdevice id="dummy_device_2" type="usesdevice">
  <propertyref refid="DCE:cdc5ee18-7ceb-4ae6-bf4c-31f983179b4d" value="dummy_device_kind_1"/>
</usesdevice>

I update the device properties:

<simple id="DCE:cdc5ee18-7ceb-4ae6-bf4c-31f983179b4d" mode="readonly" name="device_kind" type="string">
  <description>This specifies the device kind</description>
  <value>dummy_device_kind_1</value>
  <kind kindtype="configure"/>
  <kind kindtype="allocation"/>
  <action type="eq"/>
</simple>

I add the Dummy device created here into the dummy node created here. I add the Dummy Component to the Dummy Waveform. I launched the Dummy node that only contains the dummy device I launched the Dummy waveform that only contains the above dummy device. I get the following error message:

  • Failed to create application: DeviceOnlyTestWaveform_343_114533234 The following CORBA exception occurred: InvalidCapacity while creating the application IDL:CF/ApplicationFactory/CreateApplicationError:1.0*

The Domain Manager (run with Trace logging) shows the following:

 DEBUG:ApplicationFactory_impl - Trying to find the device
 TRACE:ApplicationFactory_impl - Searching for a place to deploy component amongst 1 devices
 TRACE:ApplicationFactory_impl - Checking Device DummyNode:DeviceOnlyTesTDevice_1
 TRACE:ApplicationFactory_impl - Device DummyNode:DeviceOnlyTesTDevice_1 is loadable
 TRACE:ApplicationFactory_impl - Device DummyNode:DeviceOnlyTesTDevice_1 is not loadable
 TRACE:ApplicationFactory_impl - Done checking all the devices
 DEBUG:ApplicationFactory_impl - Device Allocation Failed.. need to clean up

In ApplicationFactory_impl the code appear to show that the allocation fails since the device is not derived from Executable Device. The code section has "type" to Executable (default setting). If this is not correct then what should it be?

    // Check that the device meet's the needs of this component
    //  - Validate the type of device meets the requirements in the 'code' section of the implementation
    //
    LOG_TRACE(ApplicationFactory_impl, "Checking Device " << deviceNodeIter->identifier);
    if (deviceNodeIter->device->usageState() == CF::Device::BUSY)
    {
        LOG_TRACE(ApplicationFactory_impl, "Ignoring Device " <<deviceNodeIter->label << " is BUSY");
        continue;
    }

    if ((implementation->getCodeType() == CF::LoadableDevice::EXECUTABLE) ||
            (implementation->getCodeType() == CF::LoadableDevice::SHARED_LIBRARY)) {
        // Does this device provide LoadableDevice?
        LOG_TRACE(ApplicationFactory_impl, "Device " << deviceNodeIter->identifier << " is loadable");
        CF::LoadableDevice_var loaddev;
        loaddev = ossie::corba::_narrowSafe<CF::LoadableDevice> (deviceNodeIter->device);
        if(CORBA::is_nil(loaddev)) {
            LOG_TRACE(ApplicationFactory_impl, "Device " << deviceNodeIter->identifier << " is not loadable");
            continue;
        }

        if (implementation->getEntryPoint().size() != 0) {
            // Does this device provide ExecutableDevice?
            LOG_TRACE(ApplicationFactory_impl, "Device " << deviceNodeIter->identifier << " is executable");

            CF::ExecutableDevice_var execdev;
            execdev = ossie::corba::_narrowSafe<CF::ExecutableDevice> (deviceNodeIter->device);
            if(CORBA::is_nil(execdev)) {
                LOG_INFO(ApplicationFactory_impl, "Device " << deviceNodeIter->identifier << " is not executable");
                continue;
            }
        }
    }
2

There are 2 best solutions below

1
On BEST ANSWER

Although your device is capable of satisfying the usesdevice allocation, without a GPP or other ExecutableDevice, there is no place to run your component. There are two ways that allocation is performed when launching components:

  • Satisfying usesdevice relationships
  • Deciding on which device to deploy the executable

Each implementation in the component's SPD has a list of dependencies that must be satisfied to run the entry point. Typically, for a C++ component, this will include the OS and processor type. Additional requirements can be defined based on the processing requirements of the component, such as memory or load average; these must be allocation properties known to the target device, just like with usesdevice. There is also an implicit requirement that the device selected for deployment should support the ExecutableDevice interface (there is slightly more nuance to it, but that's by far the most common case).

When launching a waveform, the ApplicationFactory tries to allocate all required devices and select an implementation for each component in sequence. Each possible implementation is checked against all of the devices in the domain to see if there is a device that meets its dependencies. If so, the entry point for that implementation will be loaded onto the device and executed, and the ApplicationFactory moves on to the next component. If no suitable device can be found, it throws a CreateApplicationError, as you are seeing.

For most cases, you can use the GPP device included with REDHAWK to support the execution of your components. You would usually only write your own ExecutableDevice if you have a specific type of hardware that does not work with GPP, like an FPGA. If you have installed from RPM, there should be a node tailored to your local system (e.g., processor type, Java and Python versions) in your $SDRROOT/dev/nodes directory. Otherwise you can create it yourself with the 'nodeconfig.py' script included with the GPP project; see the Ubuntu installation guide for an example (admittedly, somewhat buried in the REDHAWK Manual, Appendix E, Section 5).

0
On

I believe the problem is that you don't have a GPP in the node with your Dummy Device. Because your original Device was not Executable, it was unable to execute the Component's code, which is what the GPP would do for you.

To add the GPP in the IDE, simply open up the DeviceManager.dcd.xml file of your Node, navigate to the Devices tab, and click the Add button. If everything is installed correctly, you should be able to select the GPP, then click Finish. Finally, save the Node and drag it to Target SDR and try launching it with nodeBooter again.

Also, the type "Executable" in the *.spd.xml file isn't specific to Devices. If you look at the implementation section for a Component, you'll notice there is a Type drop down under the Code section as well. The reason for this is because it isn't describing the type of Device/Component, but how the output of the build process should be interpreted.