text:
---
title: Element
template: usermanual-page.tmpl.html
position: 6
---

An Element component when in a hierarchy with a Screen Component ancestor is used to build user interfaces made up of 2D components such as images and text. The Element provides layout properties such as anchors and a pivot point.

See the [User Interface][0] section for more details.

## Group Element

The group element provides just the layout properties of the Element component

![Group Element][1]

## Image Element

The image element displays an image using a texture asset or a solid color.

![Image Element][2]

## Text Element

The text element renders a string of text using a [font asset][5].

![Text Element][3]

## Common Component Properties

    <col class="property-name"></col>
    <col class="property-description"></col>

Property	Description

Type	The type of Element: Group, Image or Text

Preset	Choosing a layout preset will automatically set the Anchor and Pivot properties to a preset value.

Anchor	Determine where the element calculates its position in relation to. See the [Layout][4] section for more information.

Pivot	Determine where the pivot point of the Element is. (0,0) is bottom left, (1,1) is top right. See the [Layout][4] section for more information.

Size	The width and height of the Element. This may be automatically calculated depending on other settings

Margin	The distance from the edge of the element to the Anchor. This is only available when the Anchor is split (non-equal in one axis).

Use Input	If enabled, this Element is added to the list of elements that check for input and fire input related events.

Layers	The Layers to render this element into. More on Layers [here][7]

Batch Group	The Batch Group that this model belongs to. More on Batching [here][8].

## Image Component Properties

    <col class="property-name"></col>
    <col class="property-description"></col>

Property	Description

Rect	Define the area of the texture asset to display.

Mask	Switch Image Element into a mask. Masks do not render into the scene, but instead limit child elements to only be rendered where this element is rendered.

Texture	The texture asset displayed

Color	The color to tint the element.

Opacity	The transparency of the element.

Layers	The Layers to render this element into. More on Layers [here][7]

## Text Component Properties

    <col class="property-name"></col>
    <col class="property-description"></col>

Property	Description

Alignment	Determine how the text is aligned with in the element. (0,0) is bottom left, (1,1) is top right.

Text	The text string to display.

Font Size	The size in Screen component pixels to render the font at.

Line Height	The size in Screen component pixels to move down for a new line.

Spacing	A multiplier to apply to the amount advanced between each character.

Font	The font asset.

Color	The color to tint the font.

Opacity	The transparency of the element.

Wrap Lines	Enable text wrapping. Any text that overflows the width of the text element will be wrapped to the next line.

Layers	The Layers to render this element into. More on Layers [here][7]

[0]: /user-manual/user-interface
[1]: /images/user-manual/scenes/components/component-element-group.png
[2]: /images/user-manual/scenes/components/component-element-image.png
[3]: /images/user-manual/scenes/components/component-element-text.png
[4]: /user-manual/user-interface/layout
[5]: /user-manual/assets/fonts/
[6]: /user-manual/optimization/batching/
[7]: /user-manual/graphics/layers
[8]: /user-manual/optimization/batching


text:
# Die Class 1: Numeric - Ch. 5.7
#### By Jeff George, 10/10/15, for DBC Phase 0

* I worked on this challenge by myself.
* I spent 4 hours on this challenge, including reading and research.

## 0. Pseudocode

**_Input:_** A class to create a die with a specified number of sides.

**_Output:_** A Die class that can report the maximum number it can roll (that is, how many sides it has), and the result of a single roll of that die. The initialization method must raise an exception (error) if asked to create a die with 0 or fewer sides.

**_Steps:_**
```
def Die(num_sides)

  def INITIALIZE a new die object
    IF num_sides < 1
      RAISE argument error
    SET number of sides = num_sides
  end

  def SIDES
    RETURN num_sides
  end

  def ROLL
    RETURN random number in range 1 to num_sides
  end

end
```

## 1. Initial Solution

```ruby
class Die

  def initialize(sides)
    if sides < 1
      raise ArgumentError, "You asked for a die with #{sides} sides. The number of sides on a die must be a positive integer."
    end
    @sides = sides
  end

  def sides
    @sides
  end

  def roll
    rand(@sides) + 1
  end

end
```

## 3. Refactored Solution

_The code in this class definition is so simple, there really isn't any refactoring to do._

## 4. Reflection

#### What is an ArgumentError and why would you use one?

An **ArgumentError** is caused when the arguments passed to a method do not match the parameters included in the method's definition. **ArgumentError**s are commonly raised when a method is passed too many or too few arguments, but it is possible to use the **raise** method to raise an **ArgumentError** to interrupt or abort the program flow for other problems with arguments. In our **Die#initialize** method, we raised an **ArgumentError** if **Die.new** were called with a "sides" argument with a value less than 1.

#### What new Ruby methods did you implement? What challenges and successes did you have in implementing them?

The two new methods (to me, at least) in this challenge were **#rand** and **#raise**. **#rand** worked exactly as I expected, based on the Ruby docs, so I had no trouble using it. **#raise** also seemed to function as I expected it to, based on my reading in the _Rubyist_, but when I tried to raise an error not just for values for **sides** that were less than 0, but also for non-integer values, my code no longer passed all the RSpec tests. In order to make it work, I had to remove the **is_a? Integer** check from the **#raise** call.

#### What is a Ruby class?

A _class_ is a group of similar objects that share certain characteristics (variables) and behaviors (methods). Every object belonging to a given class is said to be an _instance_ of that class. For example, every instance of the class **Pizza** will have an _instance variable_ that defines its size, which is written as **@size**. Not all pizzas are the same size, though, so each pizza has its own value for **@size**, independent of the sizes of other pizzas...but every instance of the pizza class must have some value for **@size**.

Similarly, if a method is created in the definition for a class, all instances of that class will be able to utilize that method. If our Pizza class has a method, **Pizza#burn_roof_of_mouth**, all pizzas will be able to use that method. So when you take a bite from any given pizza, that method is called (using something like **my_pizza.burn_roof_of_mouth**) to see if it does actually burn the roof of your mouth. The code inside **#burn_roof_of_mouth** might check a boolean instance variable named **@too_hot_to_eat?**; if **@too_hot_to_eat?** returns **true**, the pizza burns your mouth. Ouch!

#### Why would you use a Ruby class?

Ruby classes have a tremendous positive impact on both the logic and the conciseness of a program. Classes improve the logic by assuring that similar items all behave in the same way, and make programs more concise (and therefore maintainable) by eliminating huge quantities redundant code. Classes are a key weapon in the DRYness arsenal.

#### What is the difference between a local variable and an instance variable?

Instance and local variables are similar in that they are both limited in scope—that is, they are accessible only within the instance, method, or other block in which they were created. But while local variables are lost as soon as their method or block returns a value and concludes, instance variables persist as long as the object they belong to remains in existence.

Instance variables allow each instance of a class to remember its state. In our Pizza class example from above, each pizza has two instance variables, **@size** and **@too_hot_to_eat?**, which allow each pizza to keep track of information about itself. Instance variables are often set when the object is first created, by the **#initialize** method, though they can be added or adjusted later by class methods. Whenever we create a new pizza, for example, we could set the value for its **@size** with an argument to **Pizza.new**, and automatically set the value of **@too_hot_to_eat?** to **true** inside the **#initialize** method. After a certain amount of time, the value of **@too_hot_to_eat?** could be reset to **false**, probably by calling a **Pizza#cool_down** class method that checks an additional **@time_pulled_from_oven** instance variable, that would have also been set automatically at the time the pizza object was created.

#### Where can an instance variable be used?

An instance variable can be used (read, written, or changed) by methods inside the instance that it belongs to, but not by any other code elsewhere in the program. In that sense, instance variables are protected from external meddling. In order to access an instance variable, it is necessary that a class or instance method exist that uses that instance variable. For example, we can't reset a pizza object's value for **@too_hot_to_eat?** directly. We can only get to it if a class or instance variable is defined that lets us do so. In the case of our pizza class, we could call the class method **my_pizza.cool_down** to allow the pizza time to cool down, thus setting **my_pizza**'s instance variable **@too_hot_to_eat?** to false. If we want to make it too hot again, we can's just reset with a direct assignment like **my_pizza@too_hot_to_eat? = true**; we'd need to define and call a **Pizza#reheat** class method to change the value of that instance variable.

license: MIT

branch_name: refs/heads/master

extension: md

gha_language: Ruby

license_type: permissive


text:
# Eumitria implicata Stirt. SPECIES

#### Status
SYNONYM

#### According to
Index Fungorum

#### Published in
Scott. Natural. 6: 100 (1881)

#### Original name
Eumitria implicata Stirt.

### Remarks
null

repository: mdoering/backbone

path: /life/Fungi/Ascomycota/Lecanoromycetes/Lecanorales/Parmeliaceae/Eumitria/Eumitria baileyi/ Syn. Eumitria implicata/README.md

repo_name: mdoering/backbone


text:
---
layout: default
---

# 1996-08-06 - Re: Stop the presses -- Anti-terrorism bill not that bad

## Header Data

From: Alan Horowitz<EMAIL_ADDRESS>To<EMAIL_ADDRESS>Message Hash: 0b6a8b9b685415a0c8f1beb0619e6fb23120664f63c412e912b633f2ef4fbff5

Message ID<EMAIL_ADDRESS>Reply To<EMAIL_ADDRESS>UTC Datetime: 1996-08-06 08:15:07 UTC

Raw Date: Tue, 6 Aug 1996 16:15:07 +0800

## Raw message

```
{% raw  %}From: Alan Horowitz<EMAIL_ADDRESS>Date: Tue, 6 Aug 1996 16:15:07 +0800
To<EMAIL_ADDRESS>Subject: Re: Stop the presses -- Anti-terrorism bill not that bad
In-Reply-To<EMAIL_ADDRESS>Message-ID<EMAIL_ADDRESS>MIME-Version: 1.0
Content-Type: text/plain

On Tue, 6 Aug 1996<EMAIL_ADDRESS>wrote:
> Several years ago the IRA attempted to murder my cousin. I have been
> warned not to continue my political activity but I do so regardless.
>
> I do not advocate the bringing of troops onto the streets but I see
> it as the logicial response to the case put by the NRA. They are
> playing a tune I have heard before. Claim to stand for freedom while
> doing whatever is possible to encourage restriction of liberty.

  I have added you to my computerized list of individuals who advocate
the violent overthrow of the US Constitution.

I am going to go to the law library and see what my options are, with
respect to filing a petition to have you deported out of the United
States.

This is not a rhetorical statement.

{% endraw %}
```

## Thread

+ Return to [August 1996](/archive/1996/08)

+ Return to "[Alan Horowitz <alanh@infi.net>](/authors/alan_horowitz_alanh_at_infi_net_)"

+ _Unknown thread root_
  + 1996-08-06 (Tue, 6 Aug 1996 16:15:07 +0800) - Re: Stop the presses -- Anti-terrorism bill not that bad - _Alan Horowitz<EMAIL_ADDRESS>

gha_license_id: MIT


text:
# tinysat - An ATTINY13 based circuit sculpture

tinysat is based on a similar project by Mohit Bhoite - https://www.bhoite.com/sculptures/tiny-cube-sat

tinysat is comprised of an ATTINY13 blinker circuit, powered by a large capacitor and charged by a pair of solar panels.
The device is nocturnal, and uses the solar panels as a light sensor to detect when it is in darkenss, and then it will begin to blink.

repository: harrison-broadbent/tinysat

branch_name: refs/heads/main

repo_name: harrison-broadbent/tinysat


text:
---
layout: faq
title:  "How do I connect with Algorithmia?"
categories: faqs
tags: [platform-faq]
show_related: true
image:
  teaser: /icons/fa-bolt.png
---

* Follow us on [Twitter](https://twitter.com/algorithmia)!
* Check out the [Algorithmia blog](https://algorithmia.com/blog) to stay up-to-date with new features and resources for using Algorithmia.
* Contact us via our [Support Page](https://algorithmia.com/developers/support).

repository: algorithmiaio/dev-center

branch_name: refs/heads/develop

gha_language: CSS

repo_name: algorithmiaio/dev-center


text:
# PWA : Online/Offline Budget Tracker

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

### Table of Contents

- [Description](#description)
- [Installation](#installation)
- [Usage](#usage)
- [Contribution](#contribution)
- [License](#license)

## Description

The functionality of this budget tracker is to allow for offline access and functionality. The user will be able to add expenses and deposits to their budget with or without a connection. When entering transactions offline, they should populate the total when brought back online.

Offline Functionality:

- Enter deposits offline
- Enter expenses offline

When brought back online:

Offline entries will be added to tracker.

## Mock up

- The following image shows the tracker's functionality

## Home Page

![alt text](images/homepage.png)

## Installation

- Clone repository.
- `npm install`
- `node server.js`

## Usage

A demo of the application is available [here](https://calm-eyrie-65951.herokuapp.com/)

## Contribution

Please feel free in making contribution to this repository. But please first discuss the change via email with me. I will try to get back to you as soon as possible.

## Questions

If you have any questions feel free to contact me:

Github Username: sona29

Email<EMAIL_ADDRESS>
## License

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)


text:
### [CVE-2013-5593](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-5593)
![](https://img.shields.io/static/v1?label=Product&message=n%2Fa&color=blue)
![](https://img.shields.io/static/v1?label=Version&message=n%2Fa&color=blue)
![](https://img.shields.io/static/v1?label=Vulnerability&message=n%2Fa&color=brighgreen)

### Description

The SELECT element implementation in Mozilla Firefox before 25.0, Firefox ESR 24.x before 24.1, Thunderbird before 24.1, and SeaMonkey before 2.22 does not properly restrict the nature or placement of HTML within a dropdown menu, which allows remote attackers to spoof the address bar or conduct clickjacking attacks via vectors that trigger navigation off of a page containing this element.

### POC

#### Reference
- https://bugzilla.mozilla.org/show_bug.cgi?id=868327

#### Github
No PoCs found on GitHub currently.

repository: trickest/cve

gha_language: HTML

repo_name: trickest/cve


text:
@typedef {function(HTMLElement,String,CSSSelectorString,Function,can.Control)} can.Control.processor(element,eventName,selector,handler,control)

@description A function that handles the binding and unbinding of a [can.Control]'s declarative event method.

@param {HTMLElement} element the control's element or the object
specified by the templated event handler (`"{object}"`).

@param {String} eventName The event type.

@param {CSSSelectorString} selector The selector preceding the event in the binding used on the Control.

@param {function(this:can.Control,Object,Event)} handler(element, event) The callback function being bound.

@option {Object} element foo
@option {Event} event bar

@param {can.Control} control The Control the event is bound on.

@return {function()} A callback function that unbinds any event handlers bound within this processor.

@hide

repository: canjs/can-control

gha_language: JavaScript

repo_name: canjs/can-control


text:
---
title: '1.8.27 Release'
description: 'Farming payment tracker and minor improvements'
author: Adam
---

### Behavior changes since the previous update

Since the last blog post I've made a couple behavior changes without a proper blog post explaning them, leading to some confusion. Sorry about that.
These changes are:

The boosts plugin gained a new "compact view", which necessitated a new toggle for turning off the existing boosts panel display, which previously was predicated on the infobox on/off toggle. The new "Display panel" option was defaulted to off, assuming most players use the infobox display instead. If you notice the boost panel missing, go into the `Boosts information` plugin and enable `Display panel`.

Inventory tags and the left and shift-click configuration for inventory items have moved to the shift-right click menu on the items, similar to how the custom swap settings on npcs, objects, and worn items work. This makes it easier to change these settings quickly and removes the "configuration" mode where you are otherwise unable to interact with the items, which can be inconvienent. Inventory tags now supports an unlimited number of different tag "groups"/colors instead of just 6.

The party ping-tile key was made configurable due to it conflicting with the various new shift-click swaps. To use it, go to the party plugin settings and configure the hotkey.

### Farming payment tracker

The farming tracker now tracks patch payments for most trees, fruit trees, bushes. It doesn't work currently with payments to farmers who protect multiple patches, notably allotments. It is denoted via a basket of apples:

![farm](/img/blog/1.8.27-Release/farm.png)

It is still possible to see if the patch was composted, since that affects yield regardless of payment, by checking the tooltip.

### GPU improvements

Last week, we changed the underlying libraries our GPU plugin uses for interfacing with OpenGL. As part of this work, we were able to reduce the minimum OpenGL version required to run the GPU plugin to OpenGL 3.1. If you have a particularly old system which was unable to run GPU prior, it may begin to work now. The previous GPU plugin was made available on the pluginhub as `GPU (legacy)` for if you are having issues with the new plugin. Though if you are, particularly if legacy GPU works on your system and the new one doesn't, we would be interested in hearing about it on [Discord](https://runelite.net/discord).

There are also several smaller improvements and bug fixes, including:

- XP drop recolors for having the correct prayer no longer considers turning prayers on after
  the game tick but before the xp drop as successfully having the prayer on.
- A bug causing the infoboxes group to be unmovable when in the top-left corner has been fixed.
- The spec counter now much more reliably detects which hitsplat is the spec hit when hits from multiple
  sources happen at the same time (thralls/veng)
- CoX private chest has been added to antidrag
- A bug causing the world ping overlay to freeze on MacOS/Linux has been fixed
- A `hop` command has been added to world hop, eg `::hop 351`
- The loot tracker now tracks `Take-all` on seedpacks
- Various references to the dual arena has been changed to the pvp arena
- PvP arena worlds are now skipped over by the world hopper
- Object indicators now has options to highlight object outlines and clickboxes
- The spec counter now resets at Sotetseg's maze phase
- The hiscores have all been shifted back into place due to the addition of the PvP arena
- The party plugin can now overlay health, prayer, energy, special attack energy, and vengenace status on players
- The bracelet of clay tracker now correctly handles soft clay mining

Enjoy!

\- Adam

### New commits

We had 16 contributors this update!

```
Adam (61):
      menu swapper: always raise menus from low priority to cc_op
      npc indicators: add true tile highlight
      menu swapper: add global npc shift-click swap
      npc indicators: separate sw true tile and regular overlay
      party: make ping hotkey configurable
      Add rtconfig for excluded dead npcs
      Require Attack option for dying npcs
      boosts: cleanup
      boosts: add compact view
      boosts: right justify compact overlay text
      party: switch to protobuf
      entity hider: remove pvp hiding restriction
      npcutil: make rtconfig nullable
      api: add server varps
      xp drops: test server varbit for prayer active check
      menu swapper: add custom shift-click npc swap
      menu swapper: add custom shift-click object swap
      party: sanitize passphrase inputs
      tooltip: don't set overlay bounds when rendering
      spec counter: make SpecialWeapon public
      antidrag: add cox private chest
      spec counter: improve spec hitsplat detection
      spec counter: remove instanced region reset
      api: switch varc enums to use magicconstant
      ping: fix setting rcvtimeo
      ping: set SNDTIMEO
      client: update remaining getvar references
      object indicators: fix exception from under-bridge objects
      menu swapper: rename left-click swap configs to reflect they add shift too
      menu swapper: default npc shift click walk here to off
      menu swapper: add shift click walk here on objects
      menu swapper: add shift-click walk here on ground items
      spec counter: fix exception from unrecognized spec weapons
      loottracker: remove importloot
      api: add colortextureoverride
      party: exclude null from passphrase generation
      boosts: swap back (de)buff icons
      boosts: swap (de)buff icons in compat view
      boosts: fix compat view negative boosts
      world hopper: add hop command
      api: exclude dbtable
      menu swapper: use shift right click minimenu for setting up item swaps
      inv tags: add unlimited tag groups
      xptracker: initialize account and world type on startup
      clues: make findClueScroll not reset state
      clues: avoid checking clue text each tick
      change duel arena references to pvp arena
      loot tracker: add take-all for seedpacks
      menu swapper: prioritize custom swaps over hint arrow
      api: mark some tileobject methods as nullable
      menu swapper: use left click customization config
      menu swapper: sort menus by left then shift
      api: remove gameobjectchanged event
      api: remove wallobjectchanged event
      api: remove groundobjectchanged event
      api: remove decorativeobjectchanged event
      clues: remove unused tileObjectChangedHandler
      Add pvp arena world type
      timetracking: add farming payment tracker
      hiscore: add pvp arena
      hiscore panel: add pvp arena

Chintan Suthar (1):
      object indicators: add outline and clickbox highlight options

Hexagon (2):
      spec-counter: use npc index instead of id for tracking
      spec-counter: reset counter on sotetseg maze

Jordan Atwood (16):
      entity hider: Don't hide NPCs which are alive at 0hp
      game: Add more NPCs which do not die at 0hp
      game: Remove isDying block on transforming NPCs
      game: Add Giant rockslug to isDying block list
      game: Override isDying for Nex, Alchemical hydra, and Drakes
      plugins: Use isDying for loot and boss timer checks
      Add rtconfig for forced dead npcs
      api: Add Actor#setDead(boolean)
      entity hider: Hide nylocas death graphics
      game: Fix Alchemical Hydra isDying override ID
      game: Fix isDying for transforming NPCs
      game: Set Corporeal beast dead on death animation
      game: Add isDying special case for Zalcano
      npc indicators: Fix NpcUtil uses
      npc indicators: Fix dead npc highlight test
      HotColdLocation: Fix enemy for South-west of Arandar

Joshua Filby (5):
      cache: add ScriptVarType#id
      cache: add DBTableDefinition
      cache: add DBRowDefinition
      cache: add DBTableIndex
      cache: add dbtable opcodes

LlemonDuck (7):
      party: spelling generatePassphrase
      plugin manager: don't load builtin externals from hub
      party: unified player status packet
      party: extended status packet + player overlay
      party: add getMemberByDisplayName
      player indicators: highlight party members
      npc indicators: Use isDying for dead NPC checks (#15160)

Macweese (1):
      game: Add isDying support for Hopeless creature transformations (#15257)

Max Weber (5):
      cache/ParamLoader: load types correctly
      cache/ScriptVarType: add db row
      Update Quests to 2022-6-29
      questlist: update for dbtabled quests
      gpu: switch to rlawt & lwjgl

MoreBuchus (1):
      party: compact status overlay

Paul Norton (2):
      player indicators: show fc/cc ranks on friends in minimenu
      party: getMemberByDisplayName search by jagex name

Reece Camper (1):
      skill calculator: Add ensouled hellhound head to prayer actions (#15064)

Robin (1):
      game: Add lizards to isDying block list (#15144)

SirWrain (1):
      achievement diary: Fix Kourend elite blood runecrafting task text (#15128)

Spencer Kane (1):
      item charges: fix soft clay mining tracking

Timothy J. Aveni (1):
      achievement diary: Remove Ghosts Ahoy requirement from Port Phasmatys cannonball task (#15196)

Tomas Slusny (1):
      account: send username and sessionid when redirecting to /logged-in page
```


text:
# Kafka Streams Spans instrumentation
Kafka Streams is a library that runs on top of kafka clients to stream and process data from kafka.
This instrumentation module creates transaction every time records gets polled and then processed from kafka.

## Troubleshooting

If you are using kafka streams and encounter a transaction with the name: `Kafka/Streams/APPLICATION_ID_UNKNOWN`,
here are the possible causes:

1. You are using at least 2 Kafka Stream instances with the same `client.id` configured but then closed one of the streams instances.
A possible workaround is to give a different `client.id` for each instance. Another is to run each instance in a separate app.
2. If the above does not apply, and you are using the latest Kafka Streams instrumentation module, it is possible this is a silent failure created from a new
Kafka Streams version. This would likely have happened due to Kafka Streams naming their threads differently for the new version. This is because under the hood
we generally name our transactions by parsing the name of the current thread the transaction began in to get the client id. Then we use the client id to access
the `application.id` configured for your Kafka Streams instance. If this happens, please report this as this will signal us that we need a new instrumentation
module for more up-to-date Kafka Streams versions.

repository: newrelic/newrelic-java-agent

gha_language: Java

repo_name: newrelic/newrelic-java-agent


text:
### [CVE-2020-23761](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-23761)
![](https://img.shields.io/static/v1?label=Product&message=n%2Fa&color=blue)
![](https://img.shields.io/static/v1?label=Version&message=n%2Fa&color=blue)
![](https://img.shields.io/static/v1?label=Vulnerability&message=n%2Fa&color=brighgreen)

### Description

Cross Site Scripting (XSS) vulnerability in subrion CMS Version <= 4.2.1 allows remote attackers to execute arbitrary web script via the "payment gateway" column on transactions tab.

### POC

#### Reference
- http://hidden-one.co.in/2021/04/09/cve-2020-23761-stored-xss-vulnerability-in-subrion-cms-version/

#### Github
No PoCs found on GitHub currently.


text:
---
slug: student-athletes-shine-in-the-classroom
title: "Student-athletes shine in the classroom"
date: January 01 2020
---

  Led by members of the women’s soccer team, seven CSUMB squads produced team
  grade-point averages of 3.0 or higher for the spring semester.

  That’s in addition to producing two team titles, seven All-America selections,
  and a number of community service projects.

  The women soccer players compiled a 3.32 GPA to lead the university’s 12
  intercollegiate sports programs. The women's cross country and golf teams each
  compiled a 3.17.

  Men’s soccer, women’s water polo and volleyball all earned GPAs of 3.06;
  women’s basketball came in at 3.04. “CSUMB student-athletes continue to be
  challenged – not only when they compete but also in the classroom,” said CSUMB
  Director of Athletics Vince Otoupal.

  “And you know what? They are responding and they are responding well. Our GPA
  continues to improve.” Volleyball outside hitter Julia Ashen registered a
  perfect 4.0 while juggling a course load of 30 credits in her freshman year.

  Four other student-athletes recorded 4.0s for the spring semester: volleyball
  player Molly Kennedy; soccer players Dylan Niven and Kendra Gillo; and
  baseball player Brian Haggett. “Student-athletes are winning awards,” Otoupal
  said. “We are bringing home championships. We graduated 28 student-athletes
  this year and we will graduate even more next year – with better GPAs. Our
  coaches are doing a great job teaching and coaching. Our student-athletes are
  doing their jobs – in the classroom and in competition.” Softball player Jamie
  Moon became the first CSUMB student-athlete to earn Academic All-America
  honors.

  Learn more about CSUMB athletics.

repository: csumb-archives/news-gatsby

repo_name: csumb-archives/news-gatsby


text:
# movart

This work is based on previous work [here](https://github.com/boriwo/art). While _art_ does only ASCII conversion
for static images, movart does the same for mp4 encoded videos. Just like before, you can choose between monochrome,
gray scale and color characters. Movart also supports playing the audio stream if desired using the _-audio_ option.

![madness.png](madness.png)

Example Usage:

```
./movart -file video.mp4

./movart -file video.mp4 -audio

./movart -file video.mp4 -mode gray -audio

./movart -file video.mp4 -mode color -audio

./movart -file video.mp4 -alphabet "*\. " -fontfile courier_prime.ttf
```

![test.gif](test.gif)

Libraries used for this project:

_Reisen_

This project would not have been possible without _reisen_, a simple library to extract video and audio
frames from media containers.

* https://github.com/zergon321/reisen

* https://golangrepo.com/repo/zergon321-reisen-go-video

Other useful reading:

_Ebiten 2D Game Engine_

* https://github.com/hajimehoshi/ebiten

_Disintegration Imaging Library_

* https://github.com/disintegration/imaging

_OpenCV 4 Computer Vision Library_

* https://github.com/hybridgroup/gocv

repository: boriwo/movart

repo_name: boriwo/movart


text:
---
id: overview
title: Overview
sidebar_label: Overview
---

## Celerity Execution Overview

The following diagram illustrates the basics of how programs are executed
internally by the Celerity runtime system:

![Overview Image](assets/overview_image.png)

Everything starts with the user program, which is executed in single program,
multipe data (SPMD) fashion by all MPI ranks. Whenever a relevant Celerity
queue operation -- such as `submit` -- is encountered, the associated _kernel_
code is not executed directly. Instead, this code, together with some dependency
and scheduling metainformation, is recorded in the Celerity **task graph**.

Concurrently with the user program, a _command generation thread_ constructs a more
detailed **command graph** from existing task graph nodes. This command graph
includes individual instructions for the given node in the system, and also
encodes all necessary data transfers to maintain a consistent view of data
as it would be expected if the program were to be executed on a single node.
In the Celerity **distributed scheduling** scheme (introduced with Celerity 0.4.0),
only the subset of the command graph necessary for executing locally relevant
commands is created on each node, so e.g. if nodes 0 and 1 communicate with each
other locally, node 2 need not be aware of the related commands.

On each node the jobs encoded within the command graph are asynchronously
consumed by __executor threads__, which finally leads to actually running the
computations described by each kernel in the input program, distributed among
the GPUs in the cluster.

In order to make the entire process more clear, this illustration is simplified
in several aspects:

- The details of data allocations, exchange and execution are omitted.
- For this illustration, there are only three nodes in the system.
- In practice, *[Horizons](../research)*
  constrain the tasks and commands being actively processed by the system into a sliding window.

Despite these simplifications, this illustration captures the basic execution
principle of the Celerity runtime, and hopefully also makes the reasons for
some of the pitfalls described in the [Common Pitfalls](pitfalls.md) section
more clear.

repository: celerity/celerity-runtime

repo_name: celerity/celerity-runtime


text:
# Starting a Kiln stack locally
Currently, there is no automated integration testing of Kiln, but it is possible to quickly bring up a local Kiln stack to manually test changes with a Kafka cluster. Assuming you want to test a new tool image against the rest of Kiln, you will need the following components:

* Data forwarder compiled for musl-libc (to include in tool image)
* Tool image of choice (using bundler-audit as an example)
* Data collector docker image built
* Report parser docker image built
* Slack connector docker image built
* Java JRE (required for building Java Key Store for Kafka)

Parts of this process have been automated using Cargo-make, which is the task runner for the Kiln build process.

## Building the Data-forwarder binary for musl-libc
There is a Cargo-make target for building this component for musl-libc which will also run linting and unit tests.
```
cd data-forwarder
cargo make build-data-forwarder-musl
```

## Building the tool docker image
This step assumes you have already built the Data-forwarder using the previously mentioned Cargo-make target and are in the project root. The Bundler-audit `Makefile.toml` includes a set of tasks that can be used as a starting point for building new tool images.
```
cargo make tools
```

## Building the Server Components
To build the data-collector Docker image, run `cargo make server-components` from the project root. This target will be kept updated with all of the docker image targets. If you want a faster iteration cycle, you can cd into the directory of the component you're working on and run `cargo make build-COMPONENT-NAME-git-docker`.

## Configuring the slack-connector docker container
You will need to create a `.env` file in the root of the project. This path is ignored by Git, because it will contain a Slack OAuth2 token. Find the information needed by following the instructions in the Slack-connector component README.

## Generating TLS certificates
Kiln expects to connect to a Kafka cluster over TLS only, so in order to run a stack locally, we need to setup a basic PKI to ensure certificates can be validated and the connection will be successful. This process has been scripted, but still requires a small amount of user interaction.

To start the process, run the `gen_certs.sh` script in the root of the project. When prompted if you trust each certificate, enter 'yes'. This is the Java Keytool building the keystore and truststore required to connect to Kafka. This step should result in a new directory called 'tls' containing a signed CA certificate and 2 Java Keystore files containing the CA certificate and the Kafka broker certificate.

## Starting the stack
Once you've built the required docker images and generated the PKI using the `gen_certs.sh` script, you can bring up a Kiln stack. This requires two terminals, because Kiln expects that the Kafka cluster is ready to accept incoming connections when it starts.

In the first terminal, run `docker-compose up zookeeper kafka`. Once this has finished starting up and you see a message in the console output about the ToolReports topic being created, you can bring up the data-collector and report-parser by running `docker-compose up data-collector report-parser slack-connector` in the second terminal.

## Connecting the console consumer
To check the full flow of messages being consumed from the Kafka DependencyEvents topic, the easiest way is to start a Kafka console consumer. To do this, you need to `docker exec` into the Kafka broker container and from there you can start the console consumer.

Run `docker exec -it kiln_kafka_1 bash` to get a shell within the running Kafka container.

Then to start the console consumer, run `$KAFKA_HOME/bin/kafka-console-consumer.sh --bootstrap-server kafka:9092 --topic DependencyEvents --consumer.config /tls/client-ssl.properties --from-beginning`. Now if you send a valid HTTP request to the data-collector, you should see a serialised Avro message printed in this terminal.

## Running a tool image against a local Kiln stack
Using the Bundler-audit tool image as an example, this command will start the tool, mounting the current working directory for analysis and report it to a locally running Kiln stack: `docker run -it -v "${PWD}:/code" --net host -e SCAN_ENV="Local" -e APP_NAME="Railsgoat" -e DATA_COLLECTOR_URL="http://localhost:8081" kiln/bundler-audit:git-latest`

A good codebase to test this particular example on is [OWASP RailsGoat](https://github.com/OWASP/railsgoat).

## Sending an example request
You should rarely need to use these instructions. They are preserved in case changes are made to the Data-collector or downstream components and you need to test a specific failure case that isn't easy to replicate some other way.

repository: simplybusiness/Kiln

gha_language: Rust

repo_name: simplybusiness/Kiln


text:
---

---

# Security

Protecting customers' data by having secure systems is a top priority for Holiday Extras. Since the introduction of the General Data Protection Regulations (GDPR) came into force on 25th May 2018, we have updated and made public key information around our data security and privacy policies for our customers and partners.

Please see the relevant sections below for more details.

## Security Standards

To assist with understanding how we comply with GDPR, we have prepared this policy document containing details of our [security standards](https://drive.google.com/file/d/17BXVXOAiHj2aVYB8OwDqf29GR_B0DfO4/view). If you have specific questions concerning this then please contact your Account Manager.

## Business Continuity and Disaster Recovery Policy

In the event of a disaster or unforeseen event affecting our business operations, we follow internal policies and procedures. As we cannot make these publicly available, here is a summary of our [business continuity and disaster recovery policies.](https://docs.google.com/document/d/1hC4IwGUHDl0yj_8bJat8rU1DRGlFLUlSFwcMpMOmKBo/edit)

## Privacy Policy

In line with GDPR, we have updated our [Privacy Policy](https://www.holidayextras.co.uk/privacy.html) - this is applicable where we are processing customer data on behalf of our partners.

repository: holidayextras/partner-api-docs

repo_name: holidayextras/partner-api-docs


text:
# EdgeATX npm Demo [![Build Status](https://travis-ci.org/coreybutler/demomodule.png?branch=master)](https://travis-ci.org/coreybutler/demomodule)

This is a simple logging module. It can be used to generate pretty/colorized logs or plain text logs suitable for a syslog environment. This was created as a simple npm demo for the [Bleeding Edge Web Meetup](http://www.meetup.com/bleeding-edge-web/) ([slide deck](http://edgeatx.github.io/slides/2015/03-mar/#slide-32)).

## Usage

Creating a custom logger is straightforward. There are two configuration options that can be passed to a logger: `prefix` and `colorize`. By default, there is no prefix and `colorize` defaults to `true`.

```js
var CustomLogger = require('../'),
    log = new CustomLogger({
      prefix: 'Test Server'
    }),
    log2 = new CustomLogger({
      colorize: false
    });

log.log('Basic text.');
log.info('Important information.');
log.warn('Watch out!');
log.error('Uh oh! Something is awry.');

console.log('\n===========================\n');

log2.log('Basic text.');
log2.info('Important information.');
log2.warn('Watch out!');
log2.error('Uh oh! Something is awry.');
```

The code above produces:

![Screenshot](https://raw.githubusercontent.com/coreybutler/demomodule/master/demo.png)

## Installation

Download node at [nodejs.org](http://nodejs.org) and install it, if you haven't already.

```sh
npm install edgeatx-npm-demo --save
```

## Tests

**NOTICE:** You must `git clone https://github.com/edgeatx/npm-demo.git` this module to obtain tests.

```sh
npm install
npm test
```

## Dependencies

- [chalk](https://github.com/sindresorhus/chalk): Terminal string styling done right. Much color.

## Dev Dependencies

- [mocha](https://github.com/mochajs/mocha): simple, flexible, fun test framework

## License

MIT

_Generated by [package-json-to-readme](https://github.com/zeke/package-json-to-readme)_

repository: edgeATX/npm-demo

repo_name: edgeATX/npm-demo


text:
# CUDA algorithms in CMSSW

## Outline

* [Introduction](#introduction)
  * [Design goals](#design-goals)
  * [Overall guidelines](#overall-guidelines)
* [Sub-packages](#sub-packages)
* [Examples](#examples)
  * [Isolated producer (no CUDA input nor output)](#isolated-producer-no-cuda-input-nor-output)
  * [Producer with CUDA output](#producer-with-cuda-output)
  * [Producer with CUDA input](#producer-with-cuda-input)
  * [Producer with CUDA input and output (with ExternalWork)](#producer-with-cuda-input-and-output-with-externalwork)
  * [Producer with CUDA input and output, and internal chain of CPU and GPU tasks (with ExternalWork)](producer-with-cuda-input-and-output-and-internal-chain-of-cpu-and-gpu-tasks-with-externalwork)
  * [Producer with CUDA input and output (without ExternalWork)](#producer-with-cuda-input-and-output-without-externalwork)
  * [Analyzer with CUDA input](#analyzer-with-cuda-input)
  * [Configuration](#configuration)
    * [GPU-only configuration](#gpu-only-configuration)
    * [Automatic switching between CPU and GPU modules](#automatic-switching-between-cpu-and-gpu-modules)
* [More details](#more-details)
  * [Device choice](#device-choice)
  * [Data model](#data-model)
  * [CUDA EDProducer](#cuda-edproducer)
    * [Class declaration](#class-declaration)
    * [Memory allocation](#memory-allocation)
      * [Caching allocator](#caching-allocator)
      * [Non-cached pinned host `unique_ptr`](#non-cached-pinned-host-unique_ptr)
      * [CUDA API](#cuda-api)
    * [Setting the current device](#setting-the-current-device)
    * [Getting input](#getting-input)
    * [Calling the CUDA kernels](#calling-the-cuda-kernels)
    * [Putting output](#putting-output)
    * [`ExternalWork` extension](#externalwork-extension)
    * [Module-internal chain of CPU and GPU tasks](#module-internal-chain-of-cpu-and-gpu-tasks)
    * [Transferring GPU data to CPU](#transferring-gpu-data-to-cpu)
    * [Synchronizing between CUDA streams](#synchronizing-between-cuda-streams)
  * [CUDA ESProduct](#cuda-esproduct)

## Introduction

This page documents the CUDA integration within CMSSW

### Design goals

1. Provide a mechanism for a chain of modules to share a resource
   * Resource can be e.g. CUDA device memory or a CUDA stream
2. Minimize data movements between the CPU and the device
3. Support multiple devices
4. Allow the same job configuration to be used on all hardware combinations

### Overall guidelines

1. Within the `acquire()`/`produce()` functions all CUDA operations should be asynchronous, i.e.
   * Use `cudaMemcpyAsync()`, `cudaMemsetAsync()`, `cudaMemPrefetchAsync()` etc.
   * Avoid `cudaMalloc*()`, `cudaHostAlloc()`, `cudaFree*()`, `cudaHostRegister()`, `cudaHostUnregister()` on every event
     * Occasional calls are permitted through a caching mechanism that amortizes the cost (see also [Caching allocator](#caching-allocator))
   * Avoid `assert()` in device functions, or use `#include HeterogeneousCore/CUDAUtilities/interface/cuda_assert.h`
     * With the latter the `assert()` calls in CUDA code are disabled by
       default, but can be enabled by defining a `GPU_DEBUG` macro
       (before the aforementioned include)
2. Synchronization needs should be fulfilled with
   [`ExternalWork`](https://twiki.cern.ch/twiki/bin/view/CMSPublic/FWMultithreadedFrameworkStreamModuleInterface#edm_ExternalWork)
   extension to EDProducers
   * `ExternalWork` can be used to replace one synchronization point
     (e.g. between device kernels and copying a known amount of data
     back to CPU).
   * For further synchronization points (e.g. copying data whose
     amount is known only at the device side), split the work to
     multiple `ExternalWork` producers. This approach has the added
     benefit that e.g. data transfers to CPU become on-demand automatically
   * A general breakdown of the possible steps:
     * Convert input legacy CPU data format to CPU SoA
     * Transfer input CPU SoA to GPU
     * Launch kernels
     * Transfer the number of output elements to CPU
     * Transfer the output data from GPU to CPU SoA
     * Convert the output SoA to legacy CPU data formats
3. Within `acquire()`/`produce()`, the current CUDA device is set
   implicitly and the CUDA stream is provided by the system (with
   `cms::cuda::ScopedContextAcquire`/`cms::cuda::ScopedContextProduce`)
   * It is strongly recommended to use the provided CUDA stream for all operations
     * If that is not feasible for some reason, the provided CUDA
       stream must synchronize with the work queued on other CUDA
       streams (with CUDA events and `cudaStreamWaitEvent()`)
4. Outside of `acquire()`/`produce()`, CUDA API functions may be
   called only if the `CUDAService` implementation of the `CUDAInterface`
   is available and `CUDAService::enabled()` returns `true`:
     ```c++
     edm::Service<CUDAInterface> cuda;
     if (cuda and cuda->enabled()) {
       // CUDA calls ca be made here
     }
     ```
   * With point 3 it follows that in these cases multiple devices have
     to be dealt with explicitly, as well as CUDA streams

## Sub-packages
* [`HeterogeneousCore/CUDACore`](#cuda-integration) CUDA-specific core components
* [`HeterogeneousCore/CUDAServices`](../CUDAServices) Various edm::Services related to CUDA
* [`HeterogeneousCore/CUDAUtilities`](../CUDAUtilities) Various utilities for CUDA kernel code
* [`HeterogeneousCore/CUDATest`](../CUDATest) Test modules and configurations
* [`CUDADataFormats/Common`](../../CUDADataFormats/Common) Utilities for event products with CUDA data

## Examples

### Isolated producer (no CUDA input nor output)

```cpp
class IsolatedProducerCUDA: public edm::stream::EDProducer<ExternalWork> {
public:
  ...
  void acquire(edm::Event const& iEvent, edm::EventSetup const& iSetup, edm::WaitingTaskWithArenaHolder waitingTaskHolder) override;
  void produce(edm::Event& iEvent, edm::EventSetup const& iSetup) override;
  ...
private:
  ...
  IsolatedProducerGPUAlgo gpuAlgo_;
  edm::EDGetTokenT<InputData> inputToken_;
  edm::EDPutTokenT<OutputData> outputToken_;
};
...
void IsolatedProducerCUDA::acquire(edm::Event const& iEvent, edm::EventSetup const& iSetup, edm::WaitingTaskWithArenaHolder waitingTaskHolder) {
  // Sets the current device and creates a CUDA stream
  cms::cuda::ScopedContextAcquire ctx{iEvent.streamID(), std::move(waitingTaskHolder)};

  auto const& inputData = iEvent.get(inputToken_);

  // Queues asynchronous data transfers and kernels to the CUDA stream
  // returned by cms::cuda::ScopedContextAcquire::stream()
  gpuAlgo_.makeAsync(inputData, ctx.stream());

  // Destructor of ctx queues a callback to the CUDA stream notifying
  // waitingTaskHolder when the queued asynchronous work has finished
}

// Called after the asynchronous work has finished
void IsolatedProducerCUDA::produce(edm::Event& iEvent, edm::EventSetup const& iSetup) {
  // Real life is likely more complex than this simple example. Here
  // getResult() returns some data in CPU memory that is passed
  // directly to the OutputData constructor.
  iEvent.emplace(outputToken_, gpuAlgo_.getResult());
}
```

### Producer with CUDA output

```cpp
class ProducerOutputCUDA: public edm::stream::EDProducer<ExternalWork> {
public:
  ...
  void acquire(edm::Event const& iEvent, edm::EventSetup const& iSetup, edm::WaitingTaskWithArenaHolder waitingTaskHolder) override;
  void produce(edm::Event& iEvent, edm::EventSetup const& iSetup) override;
  ...
private:
  ...
  ProducerOutputGPUAlgo gpuAlgo_;
  edm::EDGetTokenT<InputData> inputToken_;
  edm::EDPutTokenT<cms::cuda::Product<OutputData>> outputToken_;
  cms::cuda::ContextState ctxState_;
};
...
void ProducerOutputCUDA::acquire(edm::Event const& iEvent, edm::EventSetup const& iSetup, edm::WaitingTaskWithArenaHolder waitingTaskHolder) {
  // Sets the current device and creates a CUDA stream
  cms::cuda::ScopedContextAcquire ctx{iEvent.streamID(), std::move(waitingTaskHolder), ctxState_};

  auto const& inputData = iEvent.get(inputToken_);

  // Queues asynchronous data transfers and kernels to the CUDA stream
  // returned by cms::cuda::ScopedContextAcquire::stream()
  gpuAlgo.makeAsync(inputData, ctx.stream());

  // Destructor of ctx queues a callback to the CUDA stream notifying
  // waitingTaskHolder when the queued asynchronous work has finished,
  // and saves the device and CUDA stream to ctxState_
}

// Called after the asynchronous work has finished
void ProducerOutputCUDA::produce(edm::Event& iEvent, edm::EventSetup const& iSetup) {
  // Sets again the current device, uses the CUDA stream created in the acquire()
  cms::cuda::ScopedContextProduce ctx{ctxState_};

  // Now getResult() returns data in GPU memory that is passed to the
  // constructor of OutputData. cms::cuda::ScopedContextProduce::emplace() wraps the
  // OutputData to cms::cuda::Product<OutputData>. cms::cuda::Product<T> stores also
  // the current device and the CUDA stream since those will be needed
  // in the consumer side.
  ctx.emplace(iEvent, outputToken_, gpuAlgo.getResult());
}
```

### Producer with CUDA input

```cpp
class ProducerInputCUDA: public edm::stream::EDProducer<ExternalWork> {
public:
  ...
  void acquire(edm::Event const& iEvent, edm::EventSetup const& iSetup, edm::WaitingTaskWithArenaHolder waitingTaskHolder) override;
  void produce(edm::Event& iEvent, edm::EventSetup const& iSetup) override;
  ...
private:
  ...
  ProducerInputGPUAlgo gpuAlgo_;
  edm::EDGetTokenT<cms::cuda:Product<InputData>> inputToken_;
  edm::EDGetTokenT<cms::cuda::Product<OtherInputData>> otherInputToken_;
  edm::EDPutTokenT<OutputData> outputToken_;
};
...
void ProducerInputCUDA::acquire(edm::Event const& iEvent, edm::EventSetup& iSetup, edm::WaitingTaskWithArenaHolder waitingTaskHolder) {
  cms::cuda::Product<InputData> const& inputDataWrapped = iEvent.get(inputToken_);

  // Set the current device to the same that was used to produce
  // InputData, and possibly use the same CUDA stream
  cms::cuda::ScopedContextAcquire ctx{inputDataWrapped, std::move(waitingTaskHolder)};

  // Grab the real input data. Checks that the input data is on the
  // current device. If the input data was produced in a different CUDA
  // stream than the cms::cuda::ScopedContextAcquire holds, create an inter-stream
  // synchronization point with CUDA event and cudaStreamWaitEvent()
  auto const& inputData = ctx.get(inputDataWrapped);

  // Input data from another producer
  auto const& otherInputData = ctx.get(iEvent.get(otherInputToken_));
  // or
  auto const& otherInputData = ctx.get(iEvent, otherInputToken_);

  // Queues asynchronous data transfers and kernels to the CUDA stream
  // returned by cms::cuda::ScopedContextAcquire::stream()
  gpuAlgo.makeAsync(inputData, otherInputData, ctx.stream());

  // Destructor of ctx queues a callback to the CUDA stream notifying
  // waitingTaskHolder when the queued asynchronous work has finished
}

// Called after the asynchronous work has finished
void ProducerInputCUDA::produce(edm::Event& iEvent, edm::EventSetup& iSetup) {
  // Real life is likely more complex than this simple example. Here
  // getResult() returns some data in CPU memory that is passed
  // directly to the OutputData constructor.
  iEvent.emplace(outputToken_, gpuAlgo_.getResult());
}
```

See [further below](#setting-the-current-device) for the conditions
when the `cms::cuda::ScopedContextAcquire` constructor reuses the CUDA stream. Note
that the `cms::cuda::ScopedContextAcquire` constructor taking `edm::StreamID` is
allowed, it will just always create a new CUDA stream.

### Producer with CUDA input and output (with ExternalWork)

```cpp
class ProducerInputOutputCUDA: public edm::stream::EDProducer<ExternalWork> {
public:
  ...
  void acquire(edm::Event const& iEvent, edm::EventSetup& iSetup, edm::WaitingTaskWithArenaHolder waitingTaskHolder) override;
  void produce(edm::Event& iEvent, edm::EventSetup& iSetup) override;
  ...
private:
  ...
  ProducerInputGPUAlgo gpuAlgo_;
  edm::EDGetTokenT<cms::cuda::Product<InputData>> inputToken_;
  edm::EDPutTokenT<cms::cuda::Product<OutputData>> outputToken_;
};
...
void ProducerInputOutputCUDA::acquire(edm::Event const& iEvent, edm::EventSetup& iSetup, edm::WaitingTaskWithArenaHolder waitingTaskHolder) {
  cms::cuda::Product<InputData> const& inputDataWrapped = iEvent.get(inputToken_);

  // Set the current device to the same that was used to produce
  // InputData, and also use the same CUDA stream
  cms::cuda::ScopedContextAcquire ctx{inputDataWrapped, std::move(waitingTaskHolder), ctxState_};

  // Grab the real input data. Checks that the input data is on the
  // current device. If the input data was produced in a different CUDA
  // stream than the cms::cuda::ScopedContextAcquire holds, create an inter-stream
  // synchronization point with CUDA event and cudaStreamWaitEvent()
  auto const& inputData = ctx.get(inputDataWrapped);

  // Queues asynchronous data transfers and kernels to the CUDA stream
  // returned by cms::cuda::ScopedContextAcquire::stream()
  gpuAlgo.makeAsync(inputData, ctx.stream());

  // Destructor of ctx queues a callback to the CUDA stream notifying
  // waitingTaskHolder when the queued asynchronous work has finished,
  // and saves the device and CUDA stream to ctxState_
}

// Called after the asynchronous work has finished
void ProducerInputOutputCUDA::produce(edm::Event& iEvent, edm::EventSetup& iSetup) {
  // Sets again the current device, uses the CUDA stream created in the acquire()
  cms::cuda::ScopedContextProduce ctx{ctxState_};

  // Now getResult() returns data in GPU memory that is passed to the
  // constructor of OutputData. cms::cuda::ScopedContextProduce::emplace() wraps the
  // OutputData to cms::cuda::Product<OutputData>. cms::cuda::Product<T> stores also
  // the current device and the CUDA stream since those will be needed
  // in the consumer side.
  ctx.emplace(iEvent, outputToken_, gpuAlgo.getResult());
}
```

[Complete example](../CUDATest/plugins/TestCUDAProducerGPUEW.cc)

### Producer with CUDA input and output, and internal chain of CPU and GPU tasks (with ExternalWork)

```cpp
class ProducerInputOutputCUDA: public edm::stream::EDProducer<ExternalWork> {
public:
  ...
  void acquire(edm::Event const& iEvent, edm::EventSetup& iSetup, edm::WaitingTaskWithArenaHolder waitingTaskHolder) override;
  void produce(edm::Event& iEvent, edm::EventSetup& iSetup) override;
  ...
private:
  void addMoreWork(edm::WaitingTaskWithArenaHolder waitingTashHolder);

  ...
  ProducerInputGPUAlgo gpuAlgo_;
  edm::EDGetTokenT<cms::cuda::Product<InputData>> inputToken_;
  edm::EDPutTokenT<cms::cuda::Product<OutputData>> outputToken_;
};
...
void ProducerInputOutputCUDA::acquire(edm::Event const& iEvent, edm::EventSetup& iSetup, edm::WaitingTaskWithArenaHolder waitingTaskHolder) {
  cms::cuda::Product<InputData> const& inputDataWrapped = iEvent.get(inputToken_);

  // Set the current device to the same that was used to produce
  // InputData, and also use the same CUDA stream
  cms::cuda::ScopedContextAcquire ctx{inputDataWrapped, std::move(waitingTaskHolder), ctxState_};

  // Grab the real input data. Checks that the input data is on the
  // current device. If the input data was produced in a different CUDA
  // stream than the cms::cuda::ScopedContextAcquire holds, create an inter-stream
  // synchronization point with CUDA event and cudaStreamWaitEvent()
  auto const& inputData = ctx.get(inputDataWrapped);

  // Queues asynchronous data transfers and kernels to the CUDA stream
  // returned by cms::cuda::ScopedContextAcquire::stream()
  gpuAlgo.makeAsync(inputData, ctx.stream());

  // Push a functor on top of "a stack of tasks" to be run as a next
  // task after the work queued above before produce(). In this case ctx
  // is a context constructed by the calling TBB task, and therefore the
  // current device and CUDA stream have been already set up. The ctx
  // internally holds the WaitingTaskWithArenaHolder for the next task.

  ctx.pushNextTask([this](cms::cuda::ScopedContextTask ctx) {
    addMoreWork(ctx);
  });

  // Destructor of ctx queues a callback to the CUDA stream notifying
  // waitingTaskHolder when the queued asynchronous work has finished,
  // and saves the device and CUDA stream to ctxState_
}

// Called after the asynchronous work queued in acquire() has finished
void ProducerInputOutputCUDA::addMoreWork(cms::cuda::ScopedContextTask& ctx) {
  // Current device and CUDA stream have already been set

  // Queues more asynchronous data transfer and kernels to the CUDA
  // stream returned by cms::cuda::ScopedContextTask::stream()
  gpuAlgo.makeMoreAsync(ctx.stream());

  // Destructor of ctx queues a callback to the CUDA stream notifying
  // waitingTaskHolder when the queued asynchronous work has finished
}

// Called after the asynchronous work queued in addMoreWork() has finished
void ProducerInputOutputCUDA::produce(edm::Event& iEvent, edm::EventSetup& iSetup) {
  // Sets again the current device, uses the CUDA stream created in the acquire()
  cms::cuda::ScopedContextProduce ctx{ctxState_};

  // Now getResult() returns data in GPU memory that is passed to the
  // constructor of OutputData. cms::cuda::ScopedContextProduce::emplace() wraps the
  // OutputData to cms::cuda::Product<OutputData>. cms::cuda::Product<T> stores also
  // the current device and the CUDA stream since those will be needed
  // in the consumer side.
  ctx.emplace(iEvent, outputToken_, gpuAlgo.getResult());
}
```

[Complete example](../CUDATest/plugins/TestCUDAProducerGPUEWTask.cc)

### Producer with CUDA input and output (without ExternalWork)

If the producer does not need to transfer anything back to CPU (like
the number of output elements), the `ExternalWork` extension is not
needed as there is no need to synchronize.

```cpp
class ProducerInputOutputCUDA: public edm::global::EDProducer<> {
public:
  ...
  void produce(edm::StreamID streamID, edm::Event& iEvent, edm::EventSetup& iSetup) const override;
  ...
private:
  ...
  ProducerInputGPUAlgo gpuAlgo_;
  edm::EDGetTokenT<cms::cuda::Product<InputData>> inputToken_;
  edm::EDPutTokenT<cms::cuda::Product<OutputData>> outputToken_;
};
...
void ProducerInputOutputCUDA::produce(edm::StreamID streamID, edm::Event& iEvent, edm::EventSetup& iSetup) const {
  cms::cuda::Product<InputData> const& inputDataWrapped = iEvent.get(inputToken_);

  // Set the current device to the same that was used to produce
  // InputData, and possibly use the same CUDA stream
  cms::cuda::ScopedContextProduce ctx{inputDataWrapped};

  // Grab the real input data. Checks that the input data is on the
  // current device. If the input data was produced in a different CUDA
  // stream than the cms::cuda::ScopedContextProduce holds, create an inter-stream
  // synchronization point with CUDA event and cudaStreamWaitEvent()
  auto const& inputData = ctx.get(inputDataWrapped);

  // Queues asynchronous data transfers and kernels to the CUDA stream
  // returned by cms::cuda::ScopedContextProduce::stream(). Here makeAsync() also
  // returns data in GPU memory that is passed to the constructor of
  // OutputData. cms::cuda::ScopedContextProduce::emplace() wraps the OutputData to
  // cms::cuda::Product<OutputData>. cms::cuda::Product<T> stores also the current
  // device and the CUDA stream since those will be needed in the
  // consumer side.
  ctx.emplace(iEvent, outputToken, gpuAlgo.makeAsync(inputData, ctx.stream());

  // Destructor of ctx queues a callback to the CUDA stream notifying
  // waitingTaskHolder when the queued asynchronous work has finished
}
```

[Complete example](../CUDATest/plugins/TestCUDAProducerGPU.cc)

### Analyzer with CUDA input

Analyzer with CUDA input is similar to [producer with CUDA
input](#producer-with-cuda-input). Note that currently we do not have
a mechanism for portable configurations with analyzers (like
[`SwitchProducer`](#automatic-switching-between-cpu-and-gpu-modules)
for producers). This means that a configuration with a CUDA analyzer
can only run on a machine with CUDA device(s).

```cpp
class AnalyzerInputCUDA: public edm::global::EDAnalyzer<> {
public:
  ...
  void analyzer(edm::Event const& iEvent, edm::EventSetup const& iSetup) override;
  ...
private:
  ...
  AnalyzerInputGPUAlgo gpuAlgo_;
  edm::EDGetTokenT<cms::cuda::Product<InputData>> inputToken_;
  edm::EDGetTokenT<cms::cuda::Product<OtherInputData>> otherInputToken_;
};
...
void AnalyzerInputCUDA::analyze(edm::Event const& iEvent, edm::EventSetup& iSetup) {
  cms::cuda::Product<InputData> const& inputDataWrapped = iEvent.get(inputToken_);

  // Set the current device to the same that was used to produce
  // InputData, and possibly use the same CUDA stream
  cms::cuda::ScopedContextAnalyze ctx{inputDataWrapped};

  // Grab the real input data. Checks that the input data is on the
  // current device. If the input data was produced in a different CUDA
  // stream than the cms::cuda::ScopedContextAnalyze holds, create an inter-stream
  // synchronization point with CUDA event and cudaStreamWaitEvent()
  auto const& inputData = ctx.get(inputDataWrapped);

  // Input data from another producer
  auto const& otherInputData = ctx.get(iEvent.get(otherInputToken_));
  // or
  auto const& otherInputData = ctx.get(iEvent, otherInputToken_);

  // Queues asynchronous data transfers and kernels to the CUDA stream
  // returned by cms::cuda::ScopedContextAnalyze::stream()
  gpuAlgo.analyzeAsync(inputData, otherInputData, ctx.stream());
}
```

[Complete example](../CUDATest/plugins/TestCUDAAnalyzerGPU.cc)

### Configuration

#### GPU-only configuration

For a GPU-only configuration there is nothing special to be done, just
construct the Paths/Sequences/Tasks from the GPU modules.

#### Automatic switching between CPU and GPU modules

The `SwitchProducer` mechanism can be used to switch automatically
between CPU and GPU modules based on the availability of GPUs on the
machine where the configuration is done. Framework decides at the
beginning of the job which of the modules to run for a given module
label.

Framework requires that the modules in the switch must produce the
same types of output products (the closer the actual results are the
better, but the framework can not enforce that). This means that for a
chain of GPU modules, it is the module that transforms the SoA data
format back to the legacy data formats (possibly, but not necessarily,
transferring the SoA data from GPU to CPU) that should be switched
between the legacy CPU module. The rest of the GPU modules should be
placed to a `Task`, in which case framework runs them only if their
output is needed by another module.

```python
from HeterogeneousCore.CUDACore.SwitchProducerCUDA import SwitchProducerCUDA
process.foo = SwitchProducerCUDA(
    cpu = cms.EDProducer("FooProducer"), # legacy CPU
    cuda = cms.EDProducer("FooProducerFromCUDA",
        src="fooCUDA"
    )
)
process.fooCUDA = cms.EDProducer("FooProducerCUDA")

process.fooTaskCUDA = cms.Task(process.fooCUDA)
process.fooTask = cms.Task(
    process.foo,
    process.fooTaskCUDA
)
```

For a more complete example, see [here](../CUDATest/test/testCUDASwitch_cfg.py).

## More details

### Device choice

As discussed above, with `SwitchProducer` the choice between CPU and
GPU modules is done at the beginning of the job.

For multi-GPU setup the device is chosen in the first CUDA module in a
chain of modules by one of the constructors of
`cms::cuda::ScopedContextAcquire`/`cms::cuda::ScopedContextProduce`
```cpp
// In ExternalWork acquire()
cms::cuda::ScopedContextAcquire ctx{iEvent.streamID(), ...};

// In normal produce() (or filter())
cms::cuda::ScopedContextProduce ctx{iEvent.streamID()};
```
As the choice is still the static EDM stream to device assignment, the
EDM stream ID is needed. The logic will likely evolve in the future to
be more dynamic, and likely the device choice has to be made for the
full event.

### Data model

The "GPU data product" should be a class/struct containing smart
pointer(s) to device data (see [Memory allocation](#memory-allocation)).
When putting the data to event, the data is wrapped to
`cms::cuda::Product<T>` template, which holds
* the GPU data product
  * must be moveable, but no other restrictions
* the current device where the data was produced, and the CUDA stream the data was produced with
* [CUDA event for synchronization between multiple CUDA streams](#synchronizing-between-cuda-streams)

Note that the `cms::cuda::Product<T>` wrapper can be constructed only with
`cms::cuda::ScopedContextProduce::wrap()`, and the data `T` can be obtained
from it only with
`cms::cuda::ScopedContextAcquire::get()`/`cms::cuda::ScopedContextProduce::get()`/`cms::cuda::ScopedContextAnalyze::get()`,
as described further below. When putting the data product directly to
`edm::Event`, also `cms::cuda::SCopedContextProduce::emplace()` can be used.

The GPU data products that depend on the CUDA runtime should be placed
under `CUDADataFormats` package, using the same name for sub-package
that would be used in `DataFormats`. Everything else, e.g. SoA for
CPU, should go under `DataFormats` as usual.

### CUDA EDProducer

#### Class declaration

The CUDA producers are normal EDProducers. The `ExternalWork`
extension should be used if a synchronization between the GPU and CPU
is needed, e.g. when transferring data from GPU to CPU.

#### Memory allocation

##### Caching allocator

The memory allocations should be done dynamically with the following functions
```cpp
#include "HeterogeneousCore/CUDAUtilities/interface/device_unique_ptr.h"
#include "HeterogeneousCore/CUDAUtilities/interface/host_unique_ptr.h"

cms::cuda::device::unique_ptr<float[]> device_buffer = cms::cuda::make_device_unique<float[]>(50, cudaStream);
cms::cuda::host::unique_ptr<float[]>   host_buffer   = cms::cuda::make_host_unique<float[]>(50, cudaStream);
```

in the `acquire()` and `produce()` functions. The same
`cudaStream_t` object that is used for transfers and kernels
should be passed to the allocator.

The allocator is based on [`cub::CachingDeviceAllocator`](https://nvlabs.github.io/cub/structcub_1_1_caching_device_allocator.html).
The memory is guaranteed to be reserved
* for the host: up to the destructor of the `unique_ptr`
* for the device: until all work queued in the `cudaStream` up to the point when the `unique_ptr` destructor is called has finished

##### Non-cached pinned host `unique_ptr`

In producers transferring data to GPU one may want to pinned host
memory allocated with `cudaHostAllocWriteCombined`. As of now we don't
want to include the flag dimension to the caching allocator. The CUDA
API wrapper library does not support allocation flags, so we add our
own `unique_ptr` for that.

```cpp
#include "HeterogeneousCore/CUDAUtilities/interface/host_noncached_unique_ptr.h"

cms::cuda::host::noncached_unique_ptr<float[]> host_buffer = cms::cuda::make_host_noncached_unique<float[]>(50, flags);
```
The `flags` is passed directly to `cudaHostAlloc()`.

##### CUDA API

The `cudaMalloc()` etc may be used outside of the event loop, but that
should be limited to only relatively small allocations in order to
allow as much re-use of device memory as possible.

If really needed, the `cudaMalloc()` etc may be used also within the
event loop, but then the cost of allocation and implicit
synchronization should be explicitly amortized e.g. by caching.

#### Setting the current device

A CUDA producer should construct `cms::cuda::ScopedContextAcquire` in
`acquire()` (`cms::cuda::ScopedContextProduce` `produce()` if not using
`ExternalWork`) either with `edm::StreamID`, or with a
`cms::cuda::Product<T>` read as an input.

```cpp
// From edm::StreamID
cms::cuda::ScopedContextAcquire ctx{iEvent.streamID(), ...};
// or
cms::cuda::ScopedContextProduce ctx{iEvent.streamID()};

// From cms::cuda::Product<T>
cms::cuda::Product<GPUClusters> const& cclus = iEvent.get(srcToken_);
cms::cuda::ScopedContextAcquire ctx{cclus, ...};
// or
cms::cuda::ScopedContextProduce ctx{cclus};
```

A CUDA analyzer should construct `cms::cuda::ScopedContextAnalyze` with a
`cms::cuda::Product<T>` read as an input.

```cpp
cms::cuda::Product<GPUClusters> const& cclus = iEvent.get(srcToken_);
cms::cuda::ScopedContextAnalyze ctx{cclus};
```

`cms::cuda::ScopedContextAcquire`/`cms::cuda::ScopedContextProduce`/`cms::cuda::ScopedContextAnalyze` work in the RAII way and does the following
* Sets the current device for the current scope
  - If constructed from the `edm::StreamID`, chooses the device and creates a new CUDA stream
  - If constructed from the `cms::cuda::Product<T>`, uses the same device and possibly the same CUDA stream as was used to produce the `cms::cuda::Product<T>`
    * The CUDA stream is reused if this producer is the first consumer
      of the `cms::cuda::Product<T>`, otherwise a new CUDA stream is created.
      This approach is simple compromise to automatically express the work of
      parallel producers in different CUDA streams, and at the same
      time allow a chain of producers to queue their work to the same
      CUDA stream.
* Gives access to the CUDA stream the algorithm should use to queue asynchronous work
* `cms::cuda::ScopedContextAcquire` calls `edm::WaitingTaskWithArenaHolder::doneWaiting()` when necessary (in its destructor)
* [Synchronizes between CUDA streams if necessary](#synchronizing-between-cuda-streams)
* Needed to get `cms::cuda::Product<T>` from the event
  * `cms::cuda::ScopedContextProduce` is needed to put `cms::cuda::Product<T>` to the event

In case of multiple input products, from possibly different CUDA
streams and/or CUDA devices, this approach gives the developer full
control in which of them the kernels of the algorithm should be run.

#### Getting input

The real product (`T`) can be obtained from `cms::cuda::Product<T>` only with
the help of
`cms::cuda::ScopedContextAcquire`/`cms::cuda::ScopedContextProduce`/`cms::cuda::ScopedContextAnalyze`.

```cpp
// From cms::cuda::Product<T>
cms::cuda::Product<GPUClusters> cclus = iEvent.get(srcToken_);
GPUClusters const& clus = ctx.get(cclus);

// Directly from Event
GPUClusters const& clus = ctx.get(iEvent, srcToken_);
```

This step is needed to
* check that the data are on the same CUDA device
  * if not, throw an exception (with unified memory could prefetch instead)
* if the CUDA streams are different, synchronize between them

#### Calling the CUDA kernels

It is usually best to wrap the CUDA kernel calls to a separate class,
and then call methods of that class from the EDProducer. The only
requirement is that the CUDA stream where to queue the operations
should be the one from the
`cms::cuda::ScopedContextAcquire`/`cms::cuda::ScopedContextProduce`/`cms::cuda::ScopedContextAnalyze`.

```cpp
gpuAlgo.makeClustersAsync(..., ctx.stream());
```

If necessary, different CUDA streams may be used internally, but they
should to be made to synchronize with the provided CUDA stream with
CUDA events and `cudaStreamWaitEvent()`.

#### Putting output

The GPU data needs to be wrapped to `cms::cuda::Product<T>` template with
`cms::cuda::ScopedContextProduce::wrap()` or `cms::cuda::ScopedContextProduce::emplace()`

```cpp
GPUClusters clusters = gpuAlgo.makeClustersAsync(..., ctx.stream());
std::unique_ptr<cms::cuda::Product<GPUClusters>> ret = ctx.wrap(clusters);
iEvent.put(std::move(ret));

// or with one line
iEvent.put(ctx.wrap(gpuAlgo.makeClustersAsync(ctx.stream())));

// or avoid one unique_ptr with emplace
edm::PutTokenT<cms::cuda::Product<GPUClusters>> putToken_ = produces<cms::cuda::Product<GPUClusters>>(); // in constructor
...
ctx.emplace(iEvent, putToken_, gpuAlgo.makeClustersAsync(ctx.stream()));
```

This step is needed to
* store the current device and CUDA stream into `cms::cuda::Product<T>`
* record the CUDA event needed for CUDA stream synchronization

#### `ExternalWork` extension

Everything above works both with and without `ExternalWork`.

Without `ExternalWork` the `EDProducer`s act similar to TBB
flowgraph's "streaming node". In other words, they just queue more
asynchronous work to the CUDA stream in their `produce()`.

The `ExternalWork` is needed when one would otherwise call
`cudeStreamSynchronize()`. For example transferring something to CPU
needed for downstream DQM, or queueing more asynchronous work. With
`ExternalWork` an `acquire()` method needs to be implemented that gets
an `edm::WaitingTaskWithArenaHolder` parameter. The
`edm::WaitingTaskWithArenaHolder` should then be passed to the
constructor of `cms::cuda::ScopedContextAcquire` along

```cpp
void acquire(..., edm::WaitingTaskWithArenaHolder waitingTaskHolder) {
  cms::cuda::Product<GPUClusters> const& cclus = iEvent.get(token_);
  cms::cuda::ScopedContextAcquire ctx{cclus, std::move(waitingTaskHolder)}; // can also copy instead of move if waitingTaskHolder is needed for something else as well
  ...
```

When constructed this way, `cms::cuda::ScopedContextAcquire` registers a
callback function to the CUDA stream in its destructor to call
`waitingTaskHolder.doneWaiting()`.

A GPU->GPU producer needs a `cms::cuda::ScopedContext` also in its
`produce()`. The device and CUDA stream are transferred via
`cms::cuda::ContextState` member variable:

```cpp
class FooProducerCUDA ... {
  ...
  cms::cuda::ContextState ctxState_;
};

void FooProducerCUDA::acquire(...) {
  ...
  cms::cuda::ScopedContextAcquire ctx{..., std::move(waitingTaskHolder), ctxState_};
  ...
}

void FooProducerCUDA::produce(...( {
  ...
  cms::cuda::ScopedContextProduce ctx{ctxState_};
}
```

The `cms::cuda::ScopedContextAcquire` saves its state to the `ctxState_` in
the destructor, and `cms::cuda::ScopedContextProduce` then restores the
context.

#### Module-internal chain of CPU and GPU tasks

Technically `ExternalWork` works such that the framework calls
`acquire()` with a `edm::WaitingTaskWithArenaHolder` that holds an
`edm::WaitingTask` (that inherits from `tbb::task`) for calling
`produce()` in a `std::shared_ptr` semantics: spawn the task when
reference count hits `0`. It is also possible to create a longer chain
of such tasks, alternating between CPU and GPU work. This mechanism
can also be used to re-run (part of) the GPU work.

The "next tasks" to run are essentially structured as a stack, such
that
- `cms::cuda::ScopedContextAcquire`/`cms::cuda::ScopedContextTask::pushNextTask()`
  pushes a new functor on top of the stack
- Completion of both the asynchronous work and the queueing function
  pops the top task of the stack and enqueues it (so that TBB
  eventually runs the task)
  * Technically the task is made eligible to run when all copies of
    `edm::WaitingTaskWithArenaHolder` of the acquire() (or "previous"
    function) have either been destructed or their `doneWaiting()` has
    been called
  * The code calling `acquire()` or the functor holds one copy of
    `edm::WaitingTaskWithArenaHolder` so it is guaranteed that the
    next function will not run before the earlier one has finished

Below is an example how to push a functor on top of the stack of tasks
to run next (following the example of the previous section)
```cpp
void FooProducerCUDA::acquire(...) {
   ...
   ctx.pushNextTask([this](cms::cuda::ScopedContextTask ctx) {
     ...
   });
   ...
}
```

In this case the `ctx`argument to the function is a
`cms::cuda::ScopedContexTask` object constructed by the TBB task calling the
user-given function. It follows that the current device and CUDA
stream have been set up already. The `pushNextTask()` can be called
many times. On each invocation the `pushNextTask()` pushes a new task
on top of the stack (i.e. in front of the chain). It follows that in
```cpp
void FooProducerCUDA::acquire(...) {
   ...
   ctx.pushNextTask([this](cms::cuda::ScopedContextTask ctx) {
     ... // function 1
   });
   ctx.pushNextTask([this](cms::cuda::ScopedContextTask ctx) {
     ... // function 2
   });
   ctx.pushNextTask([this](cms::cuda::ScopedContextTask ctx) {
     ... // function 3
   });
   ...
}
```
the functions will be run in the order 3, 2, 1.

**Note** that the `CUDAService` is **not** available (nor is any other
service) in these intermediate tasks. In the near future memory
allocations etc. will be made possible by taking them out from the
`CUDAService`.

The `cms::cuda::ScopedContextAcquire`/`cms::cuda::ScopedContextTask` have also a
more generic member function, `replaceWaitingTaskHolder()`, that can
be used to just replace the currently-hold
`edm::WaitingTaskWithArenaHolder` (that will get notified by the
callback function) with anything. In this case the caller is
responsible of creating the task(s) and setting up the chain of them.

#### Transferring GPU data to CPU

The GPU->CPU data transfer needs synchronization to ensure the CPU
memory to have all data before putting that to the event. This means
the `ExternalWork` needs to be used along
* In `acquire()`
  * (allocate CPU memory buffers)
  * Queue all GPU->CPU transfers asynchronously
* In `produce()`
  * If needed, read additional CPU products (e.g. from `edm::Ref`s)
  * Reformat data back to legacy data formats
  * Note: `cms::cuda::ScopedContextProduce` is **not** needed in `produce()`

#### Synchronizing between CUDA streams

In case the producer needs input data that were produced in two (or
more) CUDA streams, these streams have to be synchronized. Here this
synchronization is achieved with CUDA events.

Each `cms::cuda::Product<T>` constains also a CUDA event object. The call to
`cms::cuda::ScopedContextProduce::wrap()` will *record* the event in the CUDA
stream. This means that when all work queued to the CUDA stream up to
that point has been finished, the CUDA event becomes *occurred*. Then,
in
`cms::cuda::ScopedContextAcquire::get()`/`cms::cuda::ScopedContextProduce::get()`/`cms::cuda::ScopedContextAnalyze::get()`,
if the `cms::cuda::Product<T>` to get from has a different CUDA stream than
the
`cms::cuda::ScopedContextAcquire`/`cms::cuda::ScopedContextProduce`/`cms::cuda::ScopedContextAnalyze`,
`cudaStreamWaitEvent(stream, event)` is called. This means that all
subsequent work queued to the CUDA stream will wait for the CUDA event
to become occurred. Therefore this subsequent work can assume that the
to-be-getted CUDA product exists.

### CUDA ESProduct

Conditions data can be transferred to the device with the following
pattern.

1. Define a `class`/`struct` for the data to be transferred in the format accessed in the device (hereafter referred to as "payload")
2. Define a wrapper ESProduct that holds the aforementioned data in the pinned host memory
3. The wrapper should have a function returning the payload on the
   device memory. The function should transfer the data to the device
   asynchronously with the help of `cms::cuda::ESProduct<T>`.

#### Example

```cpp
#include "HeterogeneousCore/CUDACore/interface/ESProduct.h"

// Declare the struct for the payload to be transferred. Here the
// example is an array with (potentially) dynamic size. Note that all of
// below becomes simpler if the array has compile-time size.
struct ESProductExampleCUDA {
  float *someData;
  unsigned int size;
};

// Declare the wrapper ESProduct. The corresponding ESProducer should
// produce objects of this type.
class ESProductExampleCUDAWrapper {
public:
  // Constructor takes the standard CPU ESProduct, and transforms the
  // necessary data to array(s) in pinned host memory
  ESProductExampleCUDAWrapper(ESProductExample const&);

  // Deallocates all pinned host memory
  ~ESProductExampleCUDAWrapper();

  // Function to return the actual payload on the memory of the current device
  ESProductExampleCUDA const *getGPUProductAsync(cudaStream_t stream) const;

private:
  // Holds the data in pinned CPU memory
  float *someData_;
  unsigned int size_;

  // Helper struct to hold all information that has to be allocated and
  // deallocated per device
  struct GPUData {
    // Destructor should free all member pointers
    ~GPUData();
    // internal pointers are on device, struct itself is on CPU
    ESProductExampleCUDA *esproductHost = nullptr;
    // internal pounters and struct are on device
    ESProductExampleCUDA *esproductDevice = nullptr;
  };

  // Helper that takes care of complexity of transferring the data to
  // multiple devices
  cms::cuda::ESProduct<GPUData> gpuData_;
};

ESProductExampleCUDAWrapper::ESProductExampleCUDAWrapper(ESProductExample const& cpuProduct) {
  cudaCheck(cudaMallocHost(&someData_, sizeof(float)*NUM_ELEMENTS));
  // fill someData_ and size_ from cpuProduct
}

ESProductExampleCUDA const *ESProductExampleCUDAWrapper::getGPUProductAsync(cudaStream_t stream) const {
  // cms::cuda::ESProduct<T> essentially holds an array of GPUData objects,
  // one per device. If the data have already been transferred to the
  // current device (or the transfer has been queued), the helper just
  // returns a reference to that GPUData object. Otherwise, i.e. data are
  // not yet on the current device, the helper calls the lambda to do the
  // necessary memory allocations and to queue the transfers.
  auto const& data = gpuData_.dataForCurrentDeviceAsync(stream, [this](GPUData& data, cudaStream_t stream) {
    // Allocate memory. Currently this can be with the CUDA API,
    // sometime we'll migrate to the caching allocator. Assumption is
    // that IOV changes are rare enough that adding global synchronization
    // points is not that bad (for now).

    // Allocate the payload object on pinned host memory.
    cudaCheck(cudaMallocHost(&data.esproductHost, sizeof(ESProductExampleCUDA)));
    // Allocate the payload array(s) on device memory.
    cudaCheck(cudaMalloc(&data.esproductHost->someData, sizeof(float)*NUM_ELEMENTS));

    // Allocate the payload object on the device memory.
    cudaCheck(cudaMalloc(&data.esproductDevice, sizeof(ESProductDevice)));

    // Complete the host-side information on the payload
    data.cablingMapHost->size = this->size_;

    // Transfer the payload, first the array(s) ...
    cudaCheck(cudaMemcpyAsync(data.esproductHost->someData, this->someData, sizeof(float)*NUM_ELEMENTS, cudaMemcpyDefault, stream));
    // ... and then the payload object
    cudaCheck(cudaMemcpyAsync(data.esproductDevice, data.esproduceHost, sizeof(ESProductExampleCUDA), cudaMemcpyDefault, stream));
});

  // Returns the payload object on the memory of the current device
  return data.esproductDevice;
}

// Destructor frees all member pointers
ESProductExampleCUDA::GPUData::~GPUData() {
  if(esproductHost != nullptr) {
    cudaCheck(cudaFree(esproductHost->someData));
    cudaCheck(cudaFreeHost(esproductHost));
  }
  cudaCheck(cudaFree(esProductDevice));
}

```

repository: cms-sw/cmssw

repo_name: cms-sw/cmssw


text:
# Docker Compose

## Introduction

This page describes the tasks necessary to deploy Curiefense using Docker Compose. The tasks are described sequentially below:

* [Clone the Repository](docker-compose.md#clone-the-repository)
* [TLS Setup](docker-compose.md#tls-setup)
* [Set Deployment Variables](docker-compose.md#set-deployment-variables)
* [Deploy Curiefense](docker-compose.md#deploy-curiefense)
* [Test the Deployment](docker-compose.md#test-the-deployment)
* [Clean Up](docker-compose.md#clean-up)

During this process, you might find it helpful to read the descriptions (which include the purpose, secrets, and network/port details) of the services and their containers: [Services and Container Images](../../reference/services-container-images.md)

If during this process you need to rebuild an image, see the instructions here: [Building/Rebuilding an Image](../../reference/services-container-images.md#building-rebuilding-images).

## Clone the Repository

Clone the repository, if you have not already done so:

```
git clone https://github.com/curiefense/curiefense.git
```

This documentation assumes it has been cloned to `~/curiefense`.

## TLS Setup

A Docker Compose deployment can use TLS for communication with Curiefense's UI server and also for the protected service, but this is optional. (If you do not choose to set it up, HTTPS will be disabled.)

If you do not want Curiefense to use TLS, then skip this step and proceed to the next section. Otherwise, generate the certificate(s) and key(s) now.

To enable TLS for the protected site/application, go to `curiefense/deploy/compose/curiesecrets/curieproxy_ssl/` and do the following:

* Edit `site.crt` and add the certificate.
* Edit `site.key` and add the key.

To enable TLS for the nginx server that is used by `uiserver`, go to `curiefense/deploy/compose/curiesecrets/uiserver_ssl/`and do the following:

* Edit `ui.crt` and add the certificate.
* Edit `ui.key` and add the key.

## Set Deployment Variables

Docker Compose deployments can be configured in two ways:

* By setting values for variables in `deploy/compose/.env`
* Or by setting OS environment variables (which will override any variables set in`.env`)

These variables are described below.

### CURIE_BUCKET_LINK

Curiefense uses the storage defined here for synchronizing configuration changes between `confserver` and the Curiefense sidecars.

By default, this points to the `local_bucket` Docker volume:

```
$ grep CURIE_BUCKET_LINK .env
CURIE_BUCKET_LINK=file:///bucket/prod/manifest.json
```

For multi-node deployments, or to use S3 for a single node, replace this value with the URL of an S3 bucket:

```
CURIE_BUCKET_LINK=s3:///BUCKETNAME/prod/manifest.json
```

In that case, you will need to supply AWS credentials in `deploy/compose/curiesecrets/s3cfg`, following this template:

```
[default]
access_key = AAAAAAAAAAAAAAAAAAAA
secret_key = AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
```

### TARGET_ADDRESS and TARGET_PORT

The address of the destination service for which Curiefense acts as a reverse proxy. By default, this points to the `echo` container, which simply echoes the HTTP requests it receives.

### DOCKER_TAG

Defaults to `main` (the latest stable image, automatically built from the `main` branch). To run a version that matches the contents of your working directory, use the following command:

```
DOCKER_TAG="$(git describe --tag --long --dirty)-$(git rev-parse --short=12 HEAD:curiefense)"
```

## Deploy Curiefense

Once the tasks above are completed, run these commands:

```
cd curiefense/deploy/compose/
docker-compose up
```

## Test the Deployment

After deployment, the Echo service should be running and protected behind Curiefense. You can test the success of the deployment by querying it:

```
$ curl http://localhost:30081/
Request served by echo

HTTP/1.1 GET /

Host: localhost:30081
X-Envoy-Internal: true
X-Request-Id: 57dd8be5-6040-491a-903e-7ef3734ab9db
X-Envoy-Expected-Rq-Timeout-Ms: 15000
User-Agent: curl/7.74.0
Accept: */*
X-Forwarded-For: <IP_ADDRESS>
X-Forwarded-Proto: http
```

Also verify the following:

* The UIServer is now available at [http://localhost:30080](http://localhost:30080)
* Grafana is now available at [http://localhost:30300](http://localhost:30300)
* The `confserver` is now available at [http://localhost:30000/api/v1/](http://localhost:30000/api/v1/)

## Clean Up

To stop all containers and remove any persistent data stored in volumes, run the following commands:

```
docker-compose rm -f && docker volume prune -f
```


text:
# Build a Sumo Model - Assignment 5  ![robot](../img/sumo_robot.jpg)

1) Double-click on *navigate* class to open its state machine canvas.

2) Double-click the *attacking* state to open its activity editor. Paste in
the following OAL or type it in by hand:
```
select one s related by self->steering[R1];
generate steering3:straight() to s;
select one d related by self->drive[R2];
d.forward();
```
  * Save and close this activity editor

![screen](../img/sumo_hw_5.1.png)

3) Double-click the *retreating* state to open its activity editor. Paste in
the following OAL:
```
select one s related by self->steering[R1];
generate steering3:straight() to s;
select one d related by self->drive[R2];
d.reverse();
create event instance e of navigate1:pop() to self;
t = TIM::timer_start( microseconds:self.retreat_duration * 1000000, event_inst:e );
```
  * Save and close this activity editor

4) Double-click the *targeting* state to open its activity editor. Paste in
the following OAL:
```
select one d related by self->drive[R2];
d.stop();
select one s related by self->steering[R1];
generate steering1:left() to s;
create event instance e of navigate1:pop() to self;
t = TIM::timer_start( microseconds:self.target_duration * 1000000, event_inst:e );
```
  * Save and close this activity editor
  * Close this state machine canvas

5) Double-click on *steering* class to open its state machine canvas.

6) Double-click the *maintaining* state to open its activity editor. Paste in
the following OAL:
```
send IO::turn(orientation: Orientation::straight);
```
  * Save and close this activity editor

7) Double-click the *lefting* state to open its activity editor. Paste in
the following OAL:
```
send IO::turn(orientation: Orientation::left);
```
  * Save and close this activity editor

8) Double-click the *righting* state to open its activity editor. Paste in
the following OAL:
```
send IO::turn(orientation: Orientation::right);
```
  * Save and close this activity editor

### Submitting your assignment
* Take a screenshot of your *navigate* and *steering* state machines.
* Open the BridgePoint support issue you created in [homework 1.1](../homework/1.1.html).
* Edit the issue, scroll down to the Edit field:
  * Change the Status to "Feedback"
  * Change the Assignee to "cstarrett"
  * Add a Note that this assignment is completed
  * Use the Choose Files button to attach your screenshots
* Click the Submit button

[Back to assignment list](.)