Skip to content
Axel Huebl edited this page Apr 14, 2014 · 11 revisions

You are here: Home > Develop Plugins

This section will show you how to write your own plugins for PIConGPU. However, you should be familiar with how to use plugins in PIConGPU, first. Last but not least, make sure the plugin you want to create does not already exist.

Plugins in PIConGPU are based on the plugin management system of the underlying libPMacc. Hence, all plugins are ultimately derived from PMacc::IPlugin. libPMacc defines a registration/notification interface. Registered plugins can specify the period with which the want to get notified on simulation progress (iterations). Additionally, the IPlugin interface defines methods that enable program-wide checkpoints required for restarting the simulation.

Developing a lightweight plugin

All user-plugins should be created as new classes in the $PICSRC/src/picongpu/plugins/ directory. Assuming that your new plugin will be named MyPlugin create the following file MyPlugin.hpp:

#pragma once

#include "plugins/ILightweightPlugin"

namespace picongpu
{
using namespace PMacc;

class MyPlugin : public ILightweightPlugin
{
public:
  MyPlugin()
  {
    /* register our plugin during creation */
    Environment<>::get().PluginConnector().registerPlugin(this);
  }

  std::string pluginGetName() const
  {
    return "MyPlugin";
  }

  void notify(uint32_t currentStep)
  {
    /* notification callback for simulation step currentStep
     * called every notifyPeriod steps */
  }

  void pluginRegisterHelp(po::options_description& desc)
  {
    /* register command line parameters for your plugin */
    desc.add_options()
      ("myplugin.period", po::value<uint32_t > (&notifyPeriod)->default_value(0),
       "Enable MyPlugin [for each n-th step]");
  }

  void setMappingDescription(MappingDesc *cellDescription)
  {
  }

private:
  uint32_t notifyPeriod;

  void pluginLoad()
  {
    /* called when plugin is loaded, command line flags are available here
     * set notification period for our plugin at the PluginConnector */
    Environment<>::get().PluginConnector().setNotificationPeriod(this, notifyPeriod);
  }

  void pluginUnload()
  {
    /* called when plugin is unloaded, cleanup here */
  }
};
}

Then, we just need to add an instance of the plugin to $PICSRC/src/picongpu/plugins/PluginController.hpp:

#include "plugins/MyPlugin.hpp"
...
/**
* Initialises the controller by adding all user plugins to its internal list.
*/
virtual void init()
{
  ...
  /**
    * Add your plugin here, ...
    */
  plugins.push_back(new MyPlugin());
}
...

Developing a checkpoint/restart-capable plugin

PIConGPU features a checkpointing/restart mechanism that allows users to create checkpoint for certain simulation steps from which the simulation can be restarted afterwards in a new run.

To enable this mechanism for your plugin, we need to inherit from ISimulationPlugin instead of ILightweightPlugin. Given that you have the class MyPlugin from the above example, the following changes are necessary:

#include "plugins/ISimulationPlugin"

class MyPlugin : public ISimulationPlugin
{
public:
  ...
  void restart(uint32_t restartStep)
  {
    /* restart from a checkpoint here
     * will be called only once per simulation and before notify() */
  }

  void checkpoint(uint32_t currentStep)
  {
    /* create a persistent checkpoint here
     * will be called before notify() if both will be called for the same timestep */
  }
  ...
}

More information