| Response Name | Description |
| id | the ID of the domain |
| cpuavailable | the total number of cpu cores available to be created for this domain |
| cpulimit | the total number of cpu cores the domain can own |
| cputotal | the total number of cpu cores owned by domain |
| haschild | whether the domain has one or more sub-domains |
| ipavailable | the total number of public ip addresses available for this domain to acquire |
| iplimit | the total number of public ip addresses this domain can acquire |
| iptotal | the total number of public ip addresses allocated for this domain |
| level | the level of the domain |
| memoryavailable | the total memory (in MB) available to be created for this domain |
| memorylimit | the total memory (in MB) the domain can own |
| memorytotal | the total memory (in MB) owned by domain |
| name | the name of the domain |
| networkavailable | the total number of networks available to be created for this domain |
| networkdomain | the network domain |
| networklimit | the total number of networks the domain can own |
| networktotal | the total number of networks owned by domain |
| parentdomainid | the domain ID of the parent domain |
| parentdomainname | the domain name of the parent domain |
| path | the path of the domain |
| primarystorageavailable | the total primary storage space (in GiB) available to be used for this domain |
| primarystoragelimit | the total primary storage space (in GiB) the domain can own |
| primarystoragetotal | the total primary storage space (in GiB) owned by domain |
| projectavailable | the total number of projects available for administration by this domain |
| projectlimit | the total number of projects the domain can own |
| projecttotal | the total number of projects being administrated by this domain |
| secondarystorageavailable | the total secondary storage space (in GiB) available to be used for this domain |
| secondarystoragelimit | the total secondary storage space (in GiB) the domain can own |
| secondarystoragetotal | the total secondary storage space (in GiB) owned by domain |
| snapshotavailable | the total number of snapshots available for this domain |
| snapshotlimit | the total number of snapshots which can be stored by this domain |
| snapshottotal | the total number of snapshots stored by this domain |
| state | the state of the domain |
| templateavailable | the total number of templates available to be created by this domain |
| templatelimit | the total number of templates which can be created by this domain |
| templatetotal | the total number of templates which have been created by this domain |
| vmavailable | the total number of virtual machines available for this domain to acquire |
| vmlimit | the total number of virtual machines that can be deployed by this domain |
| vmtotal | the total number of virtual machines deployed by this domain |
| volumeavailable | the total volume available for this domain |
| volumelimit | the total volume which can be used by this domain |
| volumetotal | the total volume being used by this domain |
| vpcavailable | the total number of vpcs available to be created for this domain |
| vpclimit | the total number of vpcs the domain can own |
| vpctotal | the total number of vpcs owned by domain |


property Pixel[X, Y: Integer]: TColor32; default;
property PixelS[X, Y: Integer]: TColor32;
property PixelW[X, Y: Integer]: TColor32;
property PixelX[X, Y: TFixed]: TColor32;
property PixelXS[X, Y: TFixed]: TColor32;
property PixelXW[X, Y: TFixed]: TColor32;
property PixelF[X, Y: Single]: TColor32;
property PixelFS[X, Y: Single]: TColor32;
property PixelFW[X, Y: Single]: TColor32;
Pixel property sets the value of the pixel in the bitmap. Reading it, will return the color value of the pixel located at specified coordinates. This property does not validate the specified coordinates, so use it only then you are completely sure that you are not trying to read from or write to the outside of the bitmap boundary. Pixel is declared as default property, you may use it as shown below:
Bitmap32[10, 20] := Bitmap32[20, 10]; // copy a pixel from (20,10) to (10,20) position
PixelS is a 'safe' version of the Pixel property. When reading pixels from the outside the bitmap boundary, the value specified by OuterColor is returned. Writing with invalid coordinates will have no effect.
PixelW is the wrapping version of the Pixel property. When reading pixels from outside the bitmap boundary, the value returned is determined by the currently selected WrapMode. Thus always safe.
PixelX provides a method for accessing the pixels in fixed-point coordinates. The returned color is computed by performing linear interpolation on four adjacent pixels. Similarly, when pixels are set, they are antialiased.
PixelXS is a 'safe' version of the above property.
PixelXW is a wrapping version of the property PixelX.
PixelF is similar to PixelX but works with floating point coordinates instead of fixed point.
PixelFS is a 'safe' version of the above property.
PixelFW is a wrapping version of the above property.


Students give the ISSAT Exam at our partner test centres across India
Results are announced one week after the exams are conducted
Selected students appear for a Face to face interview by ISSET & universities team and ﬁnalize process for
Students submit their documents (including their Academic Results) and appear for the general English test (IELTS/PTE)
Students get a conﬁrmed oﬀer letter from the selected university & College
Process for CSR Funding along with Scholarships & Visa proceedings begins


This command generates random integers using the algorithm provided by the C standard library "rand" function included with the Microsoft Visual C++ 6 compiler. This is a linear congruential algorithm that produces quite good random numbers quickly.
The drawbacks of this algorithm are that the least significant few bits can be decidedly non-random and the cycle is fairly short (about 2^31). The first problem is not important in HexEdit as each random number is use to generate one byte and the least significant bits are not used.
The second problem means that if you generate more than about 32Kbytes of random numbers the sequence will repeat. Depending on the use of the numbers this may or may not be a problem. The numbers will still pass statistical tests of randomness but the predictability means they are not appropriate for encryption/security type applications.
For better (but slower) numbers with a much longer cycle use the Generate Good Random Numbers command.
To generate a new sequence of random numbers use the Random Seed command before repeatedly calling this command. To generate a reproducible sequence of random numbers load a specific value into the calculator and call the Seed Random Number Generator from Calculator command.


001/** 002 * Copyright 2014 Tampere University of Technology, Pori Department 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package service.tut.pori.users.google; 017 018import core.tut.pori.http.Response; 019import core.tut.pori.http.Response.Status; 020import core.tut.pori.http.annotations.HTTPAuthenticationParameter; 021import core.tut.pori.http.annotations.HTTPMethodParameter; 022import core.tut.pori.http.annotations.HTTPService; 023import core.tut.pori.http.annotations.HTTPServiceMethod; 024import core.tut.pori.http.parameters.AuthenticationParameter; 025import core.tut.pori.http.parameters.StringParameter; 026import core.tut.pori.users.UserIdentity; 027 028/** 029 * Google User Service method definitions. 030 * 031 * This class defines the APIs for registering a new account with the system and authentication using Google credentials, or more precisely, using the Google OAuth 2.0 authentication. The methods also describe the means for granting the system authorization for accessing content of the Google account. 032 * 033 * Creating an account or authenticating with Google credentials does not automatically grant the system persistent permissions for accessing the account contents. 034 * 035 * Note that the Google User Service does not contain a method for removing an existing user account. An existing account can be removed using the User Service 036 */ 037@HTTPService(name=Definitions.SERVICE_USERS_GOOGLE) 038public class GoogleUserService { 039 040 /** 041 * This method is called by Google after user has either denied or granted the service permission to his/her Google account, and is not meant to be used directly by the end-users. The method implements the OAuth2 authorization process as defined by Google. 042 * 043 * @param authorizationCode OAuth2 authorization code generated by Google. 044 * @param errorCode Optional error message as reported by Google. 045 * @param nonce Short-lived nonce value randomly generated by the authorization process. 046 * @return response 047 */ 048 @HTTPServiceMethod(name=Definitions.METHOD_OAUTH2_CALLBACK) 049 public Response oAuth2Callback( 050 @HTTPMethodParameter(name=Definitions.PARAMETER_OAUTH2_AUTHORIZATION_CODE, required=false) StringParameter authorizationCode, 051 @HTTPMethodParameter(name=Definitions.PARAMETER_OAUTH2_ERROR_CODE, required=false) StringParameter errorCode, 052 @HTTPMethodParameter(name=Definitions.PARAMETER_OAUTH2_STATE) StringParameter nonce 053 ) 054 { 055 return GoogleUserCore.processOAuth2Callback(authorizationCode.getValue(), errorCode.getValue(), nonce.getValue()); 056 } 057 058 /** 059 * This method allows a user to revoke the previously given authorization permissions. Note that calling this method does not prevent user from authenticating (logging in) using the credentials, nor will it remove the user account from the system, but calling this method will prevent the system from accessing the user's content stored in the Google account. 060 * 061 * In practice this means, that no synchronization can be performed for the account until authorization is restored. All previously synchronized content will be removed from the system. 062 * 063 * @param authenticatedUser 064 * @return response 065 */ 066 @HTTPServiceMethod(name=Definitions.METHOD_UNAUTHORIZE) 067 public Response unauthorize( 068 @HTTPAuthenticationParameter AuthenticationParameter authenticatedUser) 069 { 070 return GoogleUserCore.removeAuthorization(authenticatedUser.getUserIdentity()); 071 } 072 073 /** 074 * This method can be used to authenticate the user using Google credentials. The external account connection must be created either by registering the user as a new user using Google credentials or by authorizing the use of the Google account before the login functionality can be used. 075 * 076 * The passed access token is used to validate the user identity. The token scope should contain at least profile. Additional Google OAuth2 scopes can be present, but are not required. 077 * 078 * @param authenticatedUser 079 * @param accessToken OAuth2 access token as provided by Google. 080 * @return response 081 */ 082 @HTTPServiceMethod(name=Definitions.METHOD_LOGIN) 083 public Response login( 084 @HTTPAuthenticationParameter(required=false) AuthenticationParameter authenticatedUser, 085 @HTTPMethodParameter(name=Definitions.PARAMETER_OAUTH2_ACCESS_TOKEN) StringParameter accessToken 086 ) 087 { 088 if(UserIdentity.isValid(authenticatedUser.getUserIdentity())){ 089 return new Response(Status.BAD_REQUEST, "Already logged in. Please logout first."); 090 } 091 return GoogleUserCore.login(authenticatedUser.getSession(), accessToken.getValue()); 092 } 093 094 /** 095 * This method can be used to register a new user using a Google account. The passed access token is used to retrieve the required registration details from the account. The token scope should contain at least profile, additional Google OAuth2 scopes can be present, but are not required. 096 * 097 * The Google account is assumed to be personal, and an attempt to use the same account to create multiple accounts will result in an error. 098 * 099 * @param accessToken OAuth2 access token as provided by Google. 100 * @return response 101 */ 102 @HTTPServiceMethod(name=service.tut.pori.users.Definitions.METHOD_REGISTER) 103 public Response register(@HTTPMethodParameter(name=Definitions.PARAMETER_OAUTH2_ACCESS_TOKEN) StringParameter accessToken) 104 { 105 return GoogleUserCore.register(accessToken.getValue()); 106 } 107 108 /** 109 * This method can be used to grant the service access to the authenticated user's Google account. This method will redirect to Google's consent page asking user's permission to access the account. The default configuration will ask permissions for https://picasaweb.google.com/data/ and profile Google OAuth2 scopes, though the actual scopes required will depend on the services to be used. 110 * 111 * The authorization process will use the default OAuth2 authentication flow as implemented by Google, firstly redirecting the user to the consent page, which in turn will redirect the user back to the OAuth2 callback method. The callback method will show status message notifying the result of the authorization. 112 * 113 * The method assumes that Google accounts are personal and an attempt to authorize the same Google account for multiple users will result in error. 114 * 115 * @param authenticatedUser 116 * @return response 117 */ 118 @HTTPServiceMethod(name=Definitions.METHOD_OAUTH2_AUTHORIZATION_REDIRECT) 119 public Response authorize(@HTTPAuthenticationParameter AuthenticationParameter authenticatedUser){ 120 return GoogleUserCore.createAuthorizationRedirection(authenticatedUser.getUserIdentity()); 121 } 122}


Welcome to
AVRsack
About
AVRsack
Setting up
AVRsack
Creating and Editing Sketches
Compiling and Running Sketches
Reporting Bugs


Spain Fire Seven Goals Past Malta
by SL InternationalSpain 7-0 Malta
Spain, who have already qualified, maintained their unbeaten record at the top of Group F after hammering Malta 7-0 at Estadio Ramon de Carranza.
Alvaro Morata and Santi Cazorla got first-half goals, before La Roja ran riot in the second stanza through goals from Pau Torres, Pablo Sarabia, Daniel Olmo, Gerard Moreno and Jesus Navas.
Bosnia and Herzegovina 0-3 Italy
Italy, with their ticket to next summer's tournament already secured, kept their perfect record at the top of Group J after beating Bosnia and Herzegovina 3-0 at Stadion Bilino Polje.
Francesco Acerbi and Lorenzo Insigne gave Roberto Mancini's men a 2-0 lead going into the break, while Andrea Belotti sealed the three points in the second stanza.
Denmark 6-0 Gibraltar
Denmark are on the cusp of qualifying after thrashing Gibraltar 6-0 at Telia Parken on Friday evening.
Christian Eriksen and Robert Skov both bagged two goals each, while Christian Gytkjaer and Martin Braithwaite were also on the score-sheet for the Danes, who moved to the top of the Group D
Norway 4-0 Faroe Islands
Norway's chances of finishing among the top two sides in Group F came to an end, despite thumping Faroe Islands 4-0 at Ullevaal Stadion.
Tore Reginiussen and Iver Fossum got two early goals for the hosts, before Alexander Sorloth got a quick brace just after the hour-mark.
However Norway were made to settle for fourth spot, with 14 points - four points behind second-placed Sweden, with only one match left to play.
Switzerland 1-0 Georgia
Switzerland kept their hopes of qualifying alive with a 1-0 victory over Georgia in Group D at Kybunpark.
Cedric Itten got the crucial goal for the hosts with 13 minutes remaining to move up to second in the pool, just a point behind leaders Denmark.
Other results:
Romania 0-2 Sweden (qualified)
(qualified) Finland 3-0 Liechtenstein
Armenia 0-1 Greece
Norway 4-0 Faroe Islands


Restart game
Beginner
Intermediate
Expert
Instruction:
click
: reveal,
right-click
: set flag,
double-click
: spread reveal


Data Fields | |
| MinMaxLen | mmd |
| OnigEncoding | enc |
| OnigOptionType | options |
| OnigCaseFoldType | case_fold_flag |
| ScanEnv * | scan_env |
Definition at line 3973 of file regcomp.c.
Definition at line 3977 of file regcomp.c.
Referenced by optimize_node_left(), and set_optimize_info_from_tree().
Definition at line 3975 of file regcomp.c.
Referenced by alt_merge_node_opt_info(), alt_merge_opt_exact_info(), optimize_node_left(), and set_optimize_info_from_tree().
Definition at line 3974 of file regcomp.c.
Referenced by optimize_node_left(), and set_optimize_info_from_tree().
Definition at line 3976 of file regcomp.c.
Referenced by optimize_node_left(), and set_optimize_info_from_tree().
Definition at line 3978 of file regcomp.c.
Referenced by optimize_node_left(), and set_optimize_info_from_tree().


In 2018, 87% of global travelers reported wanting to travel sustainably.
56% said that given an option to offset their carbon footprint while traveling, they would take it.
While there is increasing awareness and availability for sustianable accommodation, sustainable travel options lag behind.
71% of consumers think that travel companies should offer sustainable options.
The global online travel market was valued at $570.25 billion in 2017.
By 2023, it could be valued at up to $1,134.55 billion.
By offering sustainable options, an environmentally responsible company
could stand to gain a much greater market share.
Statistics:
Different models of commuter aircraft have different levels of emissions.
Use the drop-down to see models used for short-range, medium-range, and long-range flights.


This page displays hosts and host patterns for which SSH client options
have been defined. These are used when the SSH client program is run
on your system to login to another SSH server, with the set of options
that apply being determined by the hostname specified in the ssh
command.
Normally by default the only options defined will be those that apply
to all client hosts. However, you can create additional sets of options
in order to control how users login to other specific servers or servers
whose names match some pattern.


@* * This template is called from the `index` template. This template * handles the rendering of the page header and body tags. It takes * two arguments, a `String` for the title of the page and an `Html` * object to insert into the body of the page. *@ @import java.util @import helper._ @(searchConditionForm: Form[SearchFilterCondition], mostPopularDiscountList: List[PopularDiscount])(implicit request: RequestHeader, messagesProvider: MessagesProvider)
| Discount | Platform |
|---|---|
| @item.discount | @item.platform |


| I l@ve RuBoard |
We use the data to do two things. First, we'll write a program that's run periodically (say, at 2 a.m., every night[3] ) and looks through the saved data, finds out which saved pickled files correspond to complaints, and prints out a customized letter to the complainant. Sounds sophisticated, but you'll be surprised at how simple it is using the right tools. Joe's web site is on a Windows machine, so we'll assume that for this program, but other platforms work in similar ways.
[3] Setting up this kind of automatic regularly scheduled program is easily done on most platforms, using, for example, cron on Unix or the AT scheduler on Windows NT.
Before we talk about how to write this program, a word about the technology it uses, namely Microsoft's Common Object Model (COM). COM is a standard for interaction between programs (an Object Request Broker service, to be technical), which allows any COM-compliant program to talk to, access the data in, and execute commands in other COM-compliant programs. Grossly, the program doing the calling is called a COM client, and the program doing the executing is called a COM server. Now, as one might suspect given the origin of COM, all major Microsoft products are COM-aware, and most can act as servers. Microsoft Word Version 8 is one of those, and the one we'll use here. Indeed, Microsoft Word is just fine for writing letters, which is what we're doing. Luckily for us, Python can be made COM-aware as well, at least on Windows 95, Windows 98, and Windows NT. Mark Hammond and Greg Stein have made available a set of extensions to Python for Windows called win32com that allow Python programs to do almost everything you can do with COM from any other language. You can write COM clients, servers, ActiveX scripting hosts, debuggers, and more, all in Python. We only need to do the first of these, which is also the simplest. Basically, our form letter program needs to do the following things:
Open all of the pickled files in the appropriate directory and unpickle them.
For each unpickled instance file, test if the feedback is a complaint. If it is, find out the name and address of the person who filled out the form and go on to Step 3. If not, skip it.
Open a Word document containing a template of the letter we want to send, and fill in the appropriate pieces with the customized information.
Print the document and close it.
It's almost as simple in Python with win32com . Here's a little program called formletter.py :
from win32com.client import constants, Dispatch WORD = 'Word.Application.8' False, True = 0, -1 import string class Word: def __init__(self): self.app = Dispatch(WORD) def open(self, doc): self.app.Documents.Open(FileName=doc) def replace(self, source, target): self.app.Selection.HomeKey(Unit=constants.wdLine) find = self.app.Selection.Find find.Text = "%"+source+"%" self.app.Selection.Find.Execute() self.app.Selection.TypeText(Text=target) def printdoc(self): self.app.Application.PrintOut() def close(self): self.app.ActiveDocument.Close(SaveChanges=False) def print_formletter(data): word.open(r"h:\David\Book\tofutemplate.doc") word.replace("name", data.name) word.replace("address", data.address) word.replace("firstname", string.split(data.name)[0]) word.printdoc() word.close() if __name__ == '__main__': import os, pickle from feedback import DIRECTORY, FormData, FeedbackData word = Word() for filename in os.listdir(DIRECTORY): data = pickle.load(open(os.path.join(DIRECTORY, filename))) if data.type == 'complaint': print "Printing letter for %(name)s." % vars(data) print_formletter(data) else: print "Got comment from %(name)s, skipping printing." % vars(data)
The first few lines of the main program show the power of a well-designed framework. The first line is a standard import statement, except that it's worth noting that win32com is a package, not a module. It is, in fact, a collection of subpackages, modules, and functions. We need two things from the win32com package: the Dispatch function in the client module, a function that allows us to "dispatch" functions to other objects (in this case COM servers), and the constants submodule of the same module, which holds the constants defined by the COM objects we want to talk to.
The second line simply defines a variable that contains the name of the COM server we're interested in. It's called Word.Application.8 , as you can find out from using a COM browser or reading Word's API (see the sidebar Finding Out About COM Interfaces).
Let's focus now on the if _ _name__ == '_ _main__' block, which is the next statement after the class and function definitions.
The first task is to read the data. We import the os and pickle modules for fairly obvious reasons, and then three references from the feedback module we just wrote: the DIRECTORY where the data is stored (this way if we change it in feedback.py, this module reflects the change the next time it's run), and the FormData and FeedbackData classes. The next line creates an instance of the Word class; this opens a connection with the Word COM server, starting the server if needed.
The for loop is a simple iteration over the files in the directory with all the saved files. It's important that this directory contain only the pickled instances, since we're not doing any error checking. As usual we should make the code more robust, but we've ignored stability for simplicity.
The first line in the for loop does the unpickling. It uses the load function from the pickle module, which takes a single argument, the file which is being unpickled. It returns as many references as were stored in the file—in our case, just one. Now, the data that was stored was just the instance of the FeedbackData class. The definition of the class itself isn't stored in the pickled file, just the instance values and a reference to the class.[4]
[4] There are very good reasons for this behavior: first, it reduces the total size of pickled objects, and more importantly, it allows you to unpickle instances of previous versions of a class and automatically upgrade them to the newer class definitions.
|
The if statement inside the loop is straightforward. All that remains is to explain is the print_formletter function, and, of course, the Word class.
The print_formletter function simply calls the various methods of the word instance of the Word class with the data extracted from the data instance. Note that we use the string.split function to extract the first name of the user, just to make the letter more friendly, but this risks strange behavior for nonstandard names.
In the Word class, the __init_ _ method appears simple yet hides a lot of work. It creates a connection with the COM server and stores a reference to that COM server in an instance variable app. Now, there are two ways in which the subsequent code might use this server: dynamic dispatch and nondynamic dispatch. In dynamic dispatch, Python doesn't "know" at the time the program is running what the interface to the COM server (in this case Microsoft Word) is. It doesn't matter, because COM allows Python to interrogate the server and determine the protocol, for example, the number and kinds of arguments each function expects. This approach can be slow, however. A way to speed it up is to run the makepy.py program, which does this once for each specified COM server and stores this information on disk. When a program using that specific server is executed, the dispatch routine uses the precomputed information rather than doing the dynamic dispatch. The program as written works in both cases. If makepy.py was run on Word in the past, the fast dispatch method is used; if not, the dynamic dispatch method is used. For more information on these issues, see the information for the win32 extensions at http://www.python.org/windows/win32all/.
To explain the Word class methods, let's start with a possible template document, so that we can see what needs to be done to it to customize it. It's shown in Figure 10.3.
As you can see, it's a pretty average document, with the exception of some text in between % signs. We've used this notation just to make it easy for a program to find the parts which need customization, but any other technique could work as well. To use this template, we need to open the document, customize it, print it, and close it. Opening it is done by the open method of the Word class. The printing and closing are done similarly. To customize, we replace the %name%, %firstname%, and %address% text with the appropriate strings. That's what the replace method of the Word class does (we won't cover how we figured out what the exact sequence of calls should be; see Finding Out About COM Interfaces for details).
Finding Out About COM InterfacesHow can you find out what the various methods and attributes of COM objects are? In general, COM objects are just like any other program; they should come with documentation. In the case of COM objects, however, it's quite possible to have the software without the documentation, simply because, as in the case of Word, it's possible to use Word without needing to program it. There are three strategies available to you if you want to explore a COM interface:
|
Putting all of this at work, the program, when run, outputs text like:
C:\Programs> python formletter.py
Printing letter for John Doe. Got comment from Your Mom, skipping printing. Printing letter for Susan B. Anthony.
and prints two customized letters, ready to be sent in the mail. Note that the Word program doesn't show up on the desktop; by default, COM servers are invisible, so Word just acts behind the scenes. If Word is currently active on the desktop, each step is visible to the user (one more reason why it's good to run these things after hours).
| I l@ve RuBoard |


paramore.brighter.commandprocessor Namespace
Classes
| Class | Description | |
|---|---|---|
| ChannelFailureException |
We raise a ChannelFailureException when we are unable to communicate with the work queue channel.
|
|
| ChannelName |
The name of a channel used to wrap communication with a Broker
|
|
| Command |
A command is an imperative instruction to do something. We expect only one receiver of a command because it is point-to-point
|
|
| CommandProcessor |
Class CommandProcessor.
Implements both the Command Dispatcher
and Command Processor Design Patterns
|
|
| CommandProcessorBuilder |
Class CommandProcessorBuilder.
Provides a fluent interface to construct a CommandProcessor. We need to identify the following dependencies in order to create a CommandProcessor
|
|
| ConfigurationException |
A ConfigurationException, thrown when we cannot configure the CommandProcessor.
|
|
| Event |
Class Event
An event is an indicator to interested parties that 'something has happened'. We expect zero to many receivers as it is one-to-many communication i.e. publish-subscribe
An event is usually fire-and-forget, because we do not know it is received.
|
|
| HandlerConfiguration |
Class HandlerConfiguration
|
|
| HandlerName |
Strongly typed class for the name of a handler
|
|
| InMemoryRequestContextFactory |
Class InMemoryRequestContextFactory
|
|
| InputChannel |
Class InputChannel.
An IAmAChannel for reading messages from a Task Queue
and acknowledging receipt of those messages
|
|
| Message | ||
| MessageBody |
Class MessageBody
The body of a Message
|
|
| MessageFactory |
Used to create off-the-shelf messages: empty, and quit, used to control processing.
|
|
| MessageHeader |
Class MessageHeader
The header for a Message
|
|
| MessageMapperRegistry |
Class MessageMapperRegistry
In order to use a Task Queue approach we require you to provide
a IAmAMessageMapper to map between Command or Event and a Message
registered via IAmAMessageMapperRegistry
This is a default implementation ofIAmAMessageMapperRegistry which is suitable for most usages, the interface is provided mainly for testing
|
|
| MessagingConfiguration |
Class MessagingConfiguration.
Used to set the components of a work queue solution
|
|
| PolicyRegistry |
Class PolicyRegistry
We use Polly policies to provide Quality of Service.
By default we provide them for a Task Queue and require you to register policies with
the policy names of:
|
|
| RequestContext |
Class RequestContext
Any pipeline has a request context that allows you to flow information between instances of IHandleRequests
The default in-memory RequestContext created by an InMemoryRequestContextFactory is suitable for most purposes
and this interface is mainly provided for testing
|
|
| RequestHandler<(Of <(<'TRequest>)>)> |
Class RequestHandler.
A target of the CommandProcessor either as the target of the Command Dispatcher to provide the domain logic required to handle the Command
or Event or as an orthogonal handler used as part of the Command Processor pipeline.
We recommend deriving your concrete handler from RequestHandler<(Of <(<'TRequest>)>)> instead of implementing the interface as it provides boilerplate
code for calling the next handler in sequence in the pipeline and describing the path
By default the [Name] is based of the Type name, and the [DescribePath] adds that [Name] into the IAmAPipelineTracer list.
By default the [Handle] method will log the calls and forward the call to the handler's [Successor]. You should call
C# base.Handle(command); |
|
| RequestHandlerAttribute |
Class RequestHandlerAttribute.
To satisfy orthogonal concerns it is possible to create a pipeline of IHandleRequests handlers. The 'target' handler should handle the domain
logic, the other handlers in the pipeline should handle Quality of Service concerns or similar orthogonal concerns. We use an approach of attributing the [IHandleRequests{T}.Handle]
method to indicate the other handlers in the pipeline that handle orthogonal concerns. This approach is preferred over fluent-pipeline configuration
because it allows you to easily see orthogonal concerns within the context of the target handler. In this sense Brighter is 'opinionated' about approach.
|
|
| RequestLoggingAttribute |
Class RequestLoggingAttribute.
Provides logging of a request using the RequestLoggingHandler<(Of <(<'TRequest>)>)>
|
|
| RequestLoggingHandler<(Of <(<'TRequest>)>)> |
Class RequestLoggingHandler.
Logs a request to a IHandleRequests handler using the Common.Logging logger registered with the CommandProcessor
The log shows the original IRequest properties as well as the timer handling.
|
|
| SubscriberRegistry |
Class SubscriberRegistry.
In order to map an IHandleRequests to a Command or an Event we need you to register the association
via the SubscriberRegistry
The default implementation of SubscriberRegistry is usable in most instances and this is provided for testing
|
Interfaces
| Interface | Description | |
|---|---|---|
| IAmAChannel |
Interface IAmAChannel
A channel is an abstraction for an OSI model Application Layer used to provide support for a
Task Queue pattern of dispatch and processing
|
|
| IAmAChannelFactory |
Interface IAmAChannelFactory
Creates instances of IAmAChannelchannels. We provide support for some Application Layer channels, and provide factories for those:
|
|
| IAmACommandProcessor |
Interface IAmACommandProcessor
Paramore.Brighter.CommandProcessor provides the default implementation of this interface CommandProcessor and it is unlikely you need
to override this for anything other than testing purposes. The usual need is that in a RequestHandler<(Of <(<'TRequest>)>)> you intend to publish an
Event to indicate the handler has completed to other components. In this case your tests should only verify that the correct
event was raised by listening to [Publish{T}] calls on this interface, using a mocking framework of your choice or bespoke
Test Double.
|
|
| IAmACommandProcessorBuilder |
Interface IAmACommandProcessorBuilder{CC2D43FA-BBC4-448A-9D0B-7B57ADF2655C}
|
|
| IAmAHandlerFactory |
Interface IAmAHandlerFactory
We do not know how to create instances of IHandleRequests implemented by your application, but need to create instances to instantiate a pipeline.
To achieve this we require clients of the Paramore.Brighter.CommandProcessor library need to implement IAmAHandlerFactory to provide
instances of their IHandleRequests types. You need to provide a Handler Factory to support all IHandleRequests registered
with IAmASubscriberRegistry. Typically you would use an IoC container to implement the Handler Factory.
|
|
| IAmALifetime |
Interface IAmALifetime
Used to manage the lifetime of objects created for the request handling pipeline
LifetimeScope for default implementation.
|
|
| IAmAMessageConsumer |
Interface IAmAReceiveMessageGateway
|
|
| IAmAMessageConsumerFactory |
Interface IAmAMessageConsumerFactory
|
|
| IAmAMessageMapper |
Interface IAmAMessageMapper
Map between a Command or an Event and a Message. You must implement this for each Command or Message you intend to send over
a Task Queue
|
|
| IAmAMessageMapper<(Of <(<'TRequest>)>)> |
Interface IAmAMessageMapper
Map between a Command or an Event and a Message. You must implement this for each Command or Message you intend to send over
a Task Queue
|
|
| IAmAMessageMapperFactory |
Interface IAmAMessageMapperFactory
In order to use a Task Queue approach we require you to provide
a IAmAMessageMapper to map between Command or Event and a Message registered via IAmAMessageMapperRegistry
We then call the instance of the factory which the client provides to create instances of that IAmAMessageMapper. You will need to implement the
IAmAMessageMapperFactory to use the Task Queue approach, and provide the instance of your mapper on request. Typically you might use an IoC container
to implement this.
|
|
| IAmAMessageMapperRegistry |
Interface IAmAMessageMapperRegistry
In order to use a Task Queue approach we require you to provide
a IAmAMessageMapper to map between Command or Event and a Message
registered via IAmAMessageMapperRegistry
The default implementationMessageMapperRegistry is suitable for most purposes and the interface is provided for testing
|
|
| IAmAMessageProducer |
Interface IAmASendMessageGateway
Abstracts away the Application Layer used to push messages onto a Task Queue
Usually clients do not need to instantiate as access is via an IAmAChannel derived class.
We provide the following default gateway applications
|
|
| IAmAMessageStore<(Of <(<'T>)>)> |
Interface IAmAMessageStore
In order to provide reliability for messages sent over a Task Queue we
store the message into a Message Store to allow later replay of those messages in the event of failure. We automatically copy any posted message into the store
We provide an implementation of IAmAMessageStore<(Of <(<'T>)>)> for Raven [RavenMessageStore]. Clients using other message stores should consider a Pull
request
|
|
| IAmAnInputChannel |
Interface IAmAnInputChannel
An IAmAChannel for reading messages from a Task Queue
and acknowledging receipt of those messages
|
|
| IAmAnOutputChannel |
Interface IAmAnOutputChannel
An IAmAChannel for pushing messages onto a Task Queue
|
|
| IAmAPipelineTracer |
Interface IAmAPipelineTracer
It can be useful to understand what IHandleRequests will be called to satisfy a request and their order
The default implementation of PipelineTracer can be used in most instances
|
|
| IAmAPolicyRegistry |
Interface IAmAPolicyRegistry
We use Polly policies to provide Quality of Service.
By default we provide them for a Task Queue and require you to register policies with
the policy names of:
|
|
| IAmARequestContextFactory |
Interface IAmARequestContextFactory
Any pipeline has a request context that allows you to flow information between instances of IHandleRequests
The default InMemoryRequestContextFactory is usable for most cases, and this interface mainly supports testing
|
|
| IAmASubscriberRegistry |
Interface IAmASubscriberRegistry
In order to map an IHandleRequests to a Command or an Event we need you to register the association
via the SubscriberRegistry
The default implementation of SubscriberRegistry is usable in most instances and this is provided for testing
|
|
| ICommand |
Interface ICommand
A command is an imperative instruction to do something. We expect only one receiver of a command because it is point-to-point
|
|
| IHandleRequests |
Interface IHandleRequests
A target of the CommandProcessor either as the target of the Command Dispatcher to provide the domain logic required to handle the Command
or Event or as an orthogonal handler used as part of the Command Processor pipeline.
We recommend deriving your concrete handler from RequestHandler<(Of <(<'TRequest>)>)> instead of implementing the interface as it provides boilerplate
code for calling the next handler in sequence in the pipeline and describing the path
The IHandleRequests interface contains a contract not dependant on the IRequest and is useful when you need to deal with a handler
without knowing the specific IRequest type, but most implementations should use IHandleRequests<(Of <(<'TRequest>)>)> directly
|
|
| IHandleRequests<(Of <(<'TRequest>)>)> |
Interface IHandleRequests
A target of the CommandProcessor either as the target of the Command Dispatcher to provide the domain logic required to handle the Command
or Event or as an orthogonal handler used as part of the Command Processor pipeline.
We recommend deriving your concrete handler from RequestHandler<(Of <(<'TRequest>)>)> instead of implementing the interface as it provides boilerplate
code for calling the next handler in sequence in the pipeline and describing the path.
It derives from IHandleRequests which provides functionality that is not dependant on IRequest. This simplifies some tasks that do not know
the specific type of the IRequest
Implementors should use on class to implement both IHandleRequests<(Of <(<'TRequest>)>)> and IHandleRequests as per RequestHandler<(Of <(<'TRequest>)>)>
|
|
| INeedAHandlers |
Interface INeedAHandlers
|
|
| INeedARequestContext |
Interface INeedARequestContext{CC2D43FA-BBC4-448A-9D0B-7B57ADF2655C}
|
|
| INeedLogging |
Interface INeedLogging{CC2D43FA-BBC4-448A-9D0B-7B57ADF2655C}
|
|
| INeedMessaging |
Interface INeedMessaging{CC2D43FA-BBC4-448A-9D0B-7B57ADF2655C}
|
|
| INeedPolicy |
Interface INeedPolicy{CC2D43FA-BBC4-448A-9D0B-7B57ADF2655C}
|
|
| IRequest | ||
| IRequestContext |
Any pipeline has a request context that allows you to flow information between instances of IHandleRequests
The default in-memory RequestContext created by an InMemoryRequestContextFactory is suitable for most purposes
and this interface is mainly provided for testing
|
Enumerations
| Enumeration | Description | |
|---|---|---|
| HandlerTiming |
Enum HandlerTiming
The Subscriber Registry registers 'target' handlers for commands or events.
A RequestHandlerAttribute identifies handlers to run in the pipeline with the target handler, to deal with 'orthogonal' concerns
Those handlers can run either before or after the target handler, and the timing value indicates where they should run
Note that handlers explicitly call the next handler in sequence, so 'child' handlers always run in the scope of their 'parent' handlers, which means
that you can choose to only execute code in a 'parent' only after a 'child' handler has executed. So you can control order of operation by that approach
and do not need to use an After handler for that.
|
|
| MessageType |
Enum MessageType
The type of a message, used on the receiving side of a Task Queue to handle the message appropriately
|


The Point object represents a point in the two dimensional space of the Paper.js project. It is also used to represent two dimensional vector objects.
Example — Create a point at x: 10, y: 5
var point = new Point(10, 5); console.log(point.x); // 10 console.log(point.y); // 5
Creates a Point object with the given x and y coordinates.
Example — Create a point at x: 10, y: 5
var point = new Point(10, 5); console.log(point.x); // 10 console.log(point.y); // 5
Creates a Point object using the numbers in the given array as coordinates.
Example — Creating a point at x: 10, y: 5 using an array of numbers:
var array = [10, 5]; var point = new Point(array); console.log(point.x); // 10 console.log(point.y); // 5
Example — Passing an array to a functionality that expects a point:
// Create a circle shaped path at x: 50, y: 50 // with a radius of 30: var path = new Path.Circle([50, 50], 30); path.fillColor = 'red'; // Which is the same as doing: var path = new Path.Circle(new Point(50, 50), 30); path.fillColor = 'red';
Creates a Point object using the properties in the given object.
Example — Creating a point using an object literal with length and angle properties:
var point = new Point({ length: 10, angle: 90 }); console.log(point.length); // 10 console.log(point.angle); // 90
Example — Creating a point at x: 10, y: 20 using an object literal:
var point = new Point({ x: 10, y: 20 }); console.log(point.x); // 10 console.log(point.y); // 20
Example — Passing an object to a functionality that expects a point:
var center = { x: 50, y: 50 }; // Creates a circle shaped path at x: 50, y: 50 // with a radius of 30: var path = new Path.Circle(center, 30); path.fillColor = 'red';
Creates a Point object using the width and height values of the given Size object.
Example — Creating a point using a size object.
// Create a Size with a width of 100pt and a height of 50pt var size = new Size(100, 50); console.log(size); // { width: 100, height: 50 } var point = new Point(size); console.log(point); // { x: 100, y: 50 }
Returns the addition of the supplied value to both coordinates of the point as a new point.
The object itself is not modified!
Example
var point = new Point(5, 10); var result = point + 20; console.log(result); // {x: 25, y: 30}
Returns the addition of the supplied point to the point as a new point.
The object itself is not modified!
Example
var point1 = new Point(5, 10); var point2 = new Point(10, 20); var result = point1 + point2; console.log(result); // {x: 15, y: 30}
Returns the subtraction of the supplied value to both coordinates of the point as a new point.
The object itself is not modified!
Example
var point = new Point(10, 20); var result = point - 5; console.log(result); // {x: 5, y: 15}
Returns the subtraction of the supplied point to the point as a new point.
The object itself is not modified!
Example
var firstPoint = new Point(10, 20); var secondPoint = new Point(5, 5); var result = firstPoint - secondPoint; console.log(result); // {x: 5, y: 15}
Returns the multiplication of the supplied value to both coordinates of the point as a new point.
The object itself is not modified!
Example
var point = new Point(10, 20); var result = point * 2; console.log(result); // {x: 20, y: 40}
Returns the multiplication of the supplied point to the point as a new point.
The object itself is not modified!
Example
var firstPoint = new Point(5, 10); var secondPoint = new Point(4, 2); var result = firstPoint * secondPoint; console.log(result); // {x: 20, y: 20}
Returns the division of the supplied value to both coordinates of the point as a new point.
The object itself is not modified!
Example
var point = new Point(10, 20); var result = point / 2; console.log(result); // {x: 5, y: 10}
Returns the division of the supplied point to the point as a new point.
The object itself is not modified!
Example
var firstPoint = new Point(8, 10); var secondPoint = new Point(2, 5); var result = firstPoint / secondPoint; console.log(result); // {x: 4, y: 2}
The modulo operator returns the integer remainders of dividing the point by the supplied value as a new point.
Example
var point = new Point(12, 6); console.log(point % 5); // {x: 2, y: 1}
The modulo operator returns the integer remainders of dividing the point by the supplied value as a new point.
Example
var point = new Point(12, 6); console.log(point % new Point(5, 2)); // {x: 2, y: 0}
The x coordinate of the point
The y coordinate of the point
The length of the vector that is represented by this point's coordinates.
Each point can be interpreted as a vector that points from the origin (x = 0, y = 0) to the point's location.
Setting the length changes the location but keeps the vector's angle.
The vector's angle in degrees, measured from the x-axis to the vector.
The vector's angle in radians, measured from the x-axis to the vector.
The quadrant of the angle of the point.
Angles between 0 and 90 degrees are in quadrant 1. Angles between 90 and 180 degrees are in quadrant 2, angles between 180 and 270 degrees are in quadrant 3 and angles between 270 and 360 degrees are in quadrant 4.
Read only.
Example
var point = new Point({ angle: 10, length: 20 }); console.log(point.quadrant); // 1 point.angle = 100; console.log(point.quadrant); // 2 point.angle = 190; console.log(point.quadrant); // 3 point.angle = 280; console.log(point.quadrant); // 4
Checks whether the coordinates of the point are equal to that of the supplied point.
Example
var point = new Point(5, 10); console.log(point == new Point(5, 10)); // true console.log(point == new Point(1, 1)); // false console.log(point != new Point(1, 1)); // true
Returns a copy of the point.
Example
var point1 = new Point(); var point2 = point1; point2.x = 1; // also changes point1.x var point2 = point1.clone(); point2.x = 1; // doesn't change point1.x
Returns the smaller angle between two vectors. The angle is unsigned, no information about rotational direction is given.
Returns the smaller angle between two vectors in radians. The angle is unsigned, no information about rotational direction is given.
Returns the distance between the point and another point.
Normalize modifies the length of the vector to 1 without changing its angle and returns it as a new point. The optional length parameter defines the length to normalize to.
The object itself is not modified!
Rotates the point by the given angle around an optional center point.
The object itself is not modified.
Read more about angle units and orientation in the description of the angle property.
Checks whether the point is inside the boundaries of the rectangle.
Checks if the point is within a given distance of another point.
Checks if the vector represented by this point is collinear (parallel) to another vector.
Checks if the vector represented by this point is orthogonal (perpendicular) to another vector.
Checks if this point has both the x and y coordinate set to 0.
Checks if this point has an undefined value for at least one of its coordinates.
Returns the dot product of the point and another point.
Returns the cross product of the point and another point.
Copyright © 2011 Jürg Lehni & Jonathan Puckey. All Rights Reserved.


© 2013, NVIDIA CORPORATION. All rights reserved.
Code and text by Sean Baxter, NVIDIA Research.
(Click here for license. Click here for contact information.)
Reduce and scan are core primitives of parallel computing. These simple implementations are compact for maximum legibility, but also support user-defined types and operators.
Scan benchmark from benchmarkscan/benchmarkscan.cu
Scan demonstration from demo/demo.cu
void DemoScan(CudaContext& context) { printf("\n\nREDUCTION AND SCAN DEMONSTRATION:\n\n"); // Generate 100 random integers between 0 and 9. int N = 100; MGPU_MEM(int) data = context.GenRandom<int>(N, 0, 9); printf("Input array:\n"); PrintArray(*data, "%4d", 10); // Run a global reduction. int total = Reduce(data->get(), N, context); printf("Reduction total: %d\n\n", total); // Run an exclusive scan. ScanExc(data->get(), N, &total, context); printf("Exclusive scan:\n"); PrintArray(*data, "%4d", 10); printf("Scan total: %d\n", total); }
REDUCTION AND SCAN DEMONSTRATION: Input array: 0: 8 1 9 8 1 9 9 2 6 3 10: 0 5 2 1 5 9 9 9 9 9 20: 1 7 9 9 9 1 4 7 8 2 30: 1 0 4 1 9 6 7 8 9 5 40: 6 7 0 3 8 2 9 6 6 3 50: 7 7 7 4 3 4 6 1 1 3 60: 7 7 0 3 2 8 0 1 0 9 70: 8 8 6 1 3 7 9 4 0 6 80: 4 1 3 2 7 0 7 0 1 4 90: 4 4 4 4 6 7 7 9 7 8 Reduction total: 492 Exclusive scan: 0: 0 8 9 18 26 27 36 45 47 53 10: 56 56 61 63 64 69 78 87 96 105 20: 114 115 122 131 140 149 150 154 161 169 30: 171 172 172 176 177 186 192 199 207 216 40: 221 227 234 234 237 245 247 256 262 268 50: 271 278 285 292 296 299 303 309 310 311 60: 314 321 328 328 331 333 341 341 342 342 70: 351 359 367 373 374 377 384 393 397 397 80: 403 407 408 411 413 420 420 427 427 428 90: 432 436 440 444 448 454 461 468 477 484 Scan total: 492
Max-reduce benchmark from benchmarkscan/benchmarkscan.cu
Max scan and reduce demonstration from demo/demo.cu
void DemoMaxReduce(CudaContext& context) { printf("\n\nMAX-REDUCE DEMONSTRATION:\n\n"); // Generate 100 random integers between 0 and 999. int N = 100; MGPU_MEM(int) data = context.GenRandom<int>(N, 0, 999); printf("Input array:\n"); PrintArray(*data, "%4d", 10); // Run a max inclusive scan.  // Provide a non-null pointer to retrieve data. template<typename InputIt, typename T, typename Op> MGPU_HOST void Reduce(InputIt data_global, int count, T identity, Op op, T* reduce_global, T* reduce_host, CudaContext& context); // T = std::iterator_traits<InputIt>::value_type. // Reduce with Op = ScanOp<ScanOpTypeAdd, T>. template<typename InputIt> MGPU_HOST typename std::iterator_traits<InputIt>::value_type Reduce(InputIt data_global, int count, CudaContext& context); //////////////////////////////////////////////////////////////////////////////// // kernels/scan.cuh // Scan inputs in device memory. // MgpuScanType may be: // MgpuScanTypeExc (exclusive) or // MgpuScanTypeInc (inclusive). // Return the total in device memory, host memory, or both. template<MgpuScanType Type, typename InputIt, typename T, typename Op, typename DestIt> MGPU_HOST void Scan(InputIt data_global, int count, T identity, Op op, T* reduce_global, T* reduce_host, DestIt dest_global, CudaContext& context); // Exclusive scan with identity = 0 and op = mgpu::plus<T>. // Returns the total in host memory. template<typename InputIt, typename TotalType> MGPU_HOST void ScanExc(InputIt data_global, int count, TotalType* total, CudaContext& context); // Like above, but don't return the total. template<typename InputIt> MGPU_HOST void ScanExc(InputIt data_global, int count, CudaContext& context);
Further Reading: For a detailed introduction to reduction networks read NVIDIA's Mark Harris on Optimizing Parallel Reduction in CUDA.
Reduce and scan (prefix sum) are core primitives in parallel computing. Reduce is the sum of elements in an input sequence:
Input: 1 7 4 0 9 4 8 8 2 4 5 5 1 7 1 1 5 2 7 6 Reduction: 87
Scan generalizes this operator, reducing inputs for every interval from the start to the current element. Exclusive scan is the sum of all inputs from the beginning to the element before the current element. Inclusive scan is the exclusive scan plus the current element. You can convert from inclusive to exclusive scan with a component-wise subtraction of the input array, or by shifting the scan one element to the right:
Input: 1 7 4 0 9 4 8 8 2 4 5 5 1 7 1 1 5 2 7 6 Exclusive: 0 1 8 12 12 21 25 33 41 43 47 52 57 58 65 66 67 72 74 81 Inclusive: 1 8 12 12 21 25 33 41 43 47 52 57 58 65 66 67 72 74 81 87
Note that the last element of inclusive scan is the reduction of the inputs.
Parallel evaluation of reduce and scan requires cooperative scan networks which sacrifice work efficiency to expose parallelism.
For reduction, we recursively fold values together:
Input: 1 7 4 0 9 4 8 8 2 4 5 5 1 7 1 1 5 2 7 6 Reduce progress by pass: 1: 1 7 4 0 9 4 8 8 2 4 + 5 5 1 7 1 1 5 2 7 6 6 12 5 7 10 5 13 10 9 10 2: 6 12 5 7 10 + 5 13 10 9 10 11 25 15 16 20 3: 11 25 15 + 16 20 11 41 35 4: 11 41 + 35 11 76 4: 11 + 76 87
On the first pass, each thread in the left half of the CTA loads its corresponding value on the right half of the CTA, adds it into its own value, and stores the result back. On the second pass, the first quarter of the threads load values for the next quarter, add, and store. This is repeated log(N) times until all values in the tile have been folded together. The number of additions is still N-1 in this parallel implementation, although there is a loss of efficiency due to branch divergence when the number of active lanes is less than one warp's width.
This implementation of reduction requires both associativity and commutativity in the operator. Although commutativity can be relaxed by re-ordering inputs, associativity is generally required for all parallel computation.
Consider the cooperative scan network based on the Kogge-Stone adder. n inputs are processed in log(n) passes. On pass 0, element i - 1 (if in range) is added into element i, in parallel. On pass 1, element i - 2 is added into element i. On pass 2, element i - 4 is added into element i, and so on.
Input: 1 7 4 0 9 4 8 8 2 4 5 5 1 7 1 1 5 2 7 6 Inclusive scan network by offset: 1: 1 8 11 4 9 13 12 16 10 6 9 10 6 8 8 2 6 7 9 13 2: 1 8 12 12 20 17 21 29 22 22 19 16 15 18 14 10 14 9 15 20 4: 1 8 12 12 21 25 33 41 42 39 40 45 37 40 33 26 29 27 29 30 8: 1 8 12 12 21 25 33 41 43 47 52 57 58 65 66 67 71 66 69 75 16: 1 8 12 12 21 25 33 41 43 47 52 57 58 65 66 67 72 74 81 87 Exclusive: 0 1 8 12 12 21 25 33 41 43 47 52 57 58 65 66 67 72 74 81
On each pass, the element in red (column 17 - offset) is added into the element in green (column 17) and stored at column 17 on the next line. By the last pass this chain of adders has communicated the sum of all elements between columns 0 and 16 into column 17.
The sequential implementation runs in O(n) operations with O(n) latency. The parallel version has O(n log n) work efficiency, but by breaking the serial dependencies, improves latency to O(log n) on machines with n processors.
Most workloads have many more inputs than the device has processors. Processing large inputs with the parallel reduce and scan networks described above is not practical, due to the required synchronization between each pass.
In the case of reduce, the parallel network requries more data movement than an optimal implementation. In the case of scan, the parallel network requires both more data movement and more computation, due to O(n log n) algorithmic complexity for an operation that should be linear.
We use register blocking to improve work-efficiency and reduce synchronization. This general parallel-computing strategy assigns multiple values to each thread, which are processed sequentially. Each thread's local reduction may then be processed with a parallel reduce or scan network, or fed back into a function that again processes inputs with register blocking.
Nearly all Modern GPU routines are register blocked. The number of values assigned to a thread is the grain size, which we refer to as VT (values per thread). Grain size becomes the primary tuning parameter for finding optimal performance on each GPU architecture:
Increasing grain size does more sequential processing per thread, improving overall work-efficiency, but also uses more per-thread state, reducing occupancy and compromising the device's ability to hide latency.
Decreasing grain size does less sequential processing per thread, decreasing overall work-efficiency, but also uses less per-thread state, increasing occupancy and enabling the device to better hide latency.
Register blocking with scan leads results in a common three-phase process. The use of sequential operations in this parallel algorithm are called "raking reductions" and "raking scans," because they are computed within lanes rather than cooperatively over the lanes.
Upsweep to send partial reductions to the spine. Each CTA/thread sequentially reduces its assignment of inputs and stores to global/shahred memory. This is the carry-out value for the CTA/thread.
Scan the spine of partials. Exclusive scan the carry-out values produced in step 1. This turns carry-out values into carry-in values.
Downsweep to distribute scanned partials from the spine to each of the inputs. Each CTA/thread sequentially scans its assignment of inputs, adding the carry-in (the output of step 2) into each scanned value.
Register blocking with reduce requires only repeated application of the upsweep phase until all values are folded into one carry-out.
Input array: 20 threads and 5 elements/thread: 1 7 4 0 9 4 8 8 2 4 5 5 1 7 1 1 5 2 7 6 1 4 2 3 2 2 1 6 8 5 7 6 1 8 9 2 7 9 5 4 3 1 2 3 3 4 1 1 3 8 7 4 2 7 7 9 3 1 9 8 6 5 0 2 8 6 0 2 4 8 6 5 0 9 0 0 6 1 3 8 9 3 4 4 6 0 6 6 1 8 4 9 6 3 7 8 8 2 9 1 Partial reduction by threads (Upsweep): 21 26 19 21 12 22 31 27 12 17 27 30 21 20 20 18 26 21 29 28 Parallel scan of partials (Spine): 1: 21 47 45 40 33 34 53 58 39 29 44 57 51 41 40 38 44 47 50 57 2: 21 47 66 87 78 74 86 92 92 87 83 86 95 98 91 79 84 85 94 104 4: 21 47 66 87 99 121 152 179 170 161 169 178 187 185 174 165 179 183 185 183 8: 21 47 66 87 99 121 152 179 191 208 235 265 286 306 326 344 349 344 354 361 16: 21 47 66 87 99 121 152 179 191 208 235 265 286 306 326 344 370 391 420 448 Exclusive scan of partials: 0 21 47 66 87 99 121 152 179 191 208 235 265 286 306 326 344 370 391 420 Add exclusive scan of partials into exclusive sequential scan of input array (Downsweep): 0 1 8 12 12 21 25 33 41 43 47 52 57 58 65 66 67 72 74 81 87 88 92 94 97 99 101 102 108 116 121 128 134 135 143 152 154 161 170 175 179 182 183 185 188 191 195 196 197 200 208 215 219 221 228 235 244 247 248 257 265 271 276 276 278 286 292 292 294 298 306 312 317 317 326 326 326 332 333 336 344 353 356 360 364 370 370 376 382 383 391 395 404 410 413 420 428 436 438 447
The figure above illustrates the raking scan pattern, using 20 threads to cooperatively scan 100 inputs. During the upsweep phase, each thread reduces five inputs using a work-efficient serial loop. The 20 partials are then scanned in parallel using five parallel scan passes. During the downsweep phase, each thread sequentially adds its five inputs into the scanned partial from the spine. By increasing the grain size (the parameter VT in MGPU kernels) we do more linear-complexity work to amortize the O(n log n) scan network cost.
The previous update defined a scan op interface with several typedefs and four methods. It also supported operators that were commutative (high-speed, preferred) and non-commutative. This allowed for maximum flexibility. The new update removes this complicated interface and replaces it with a simple functor object and an identity value.
template<typename T> struct plus : public std::binary_function<T, T, T> { MGPU_HOST_DEVICE T operator()(T a, T b) { return a + b; } }; template<typename T> struct minus : public std::binary_function<T, T, T> { MGPU_HOST_DEVICE T operator()(T a, T b) { return a - b; } }; template<typename T> struct multiplies : public std::binary_function<T, T, T> { MGPU_HOST_DEVICE T operator()(T a, T b) { return a * b; } };
To use reduce or scan, define a class which inherits std::binary_function
and implements a two-argument operator()
method. These are device-compatible versions of std::plus
, std::minus
, etc.
Reduce and scan functions also require an identity argument. This value is arithmetically neutral with respect to the operator. The identity for mgpu::plus
is 0; the identity for mpgu::multiplies
is 1, etc. This term is not strictly requried for computing reduction or inclusive scan (exclusive scan needs it for the first element), but the MGPU library uses it to significantly simplify implementation.
template<int NT, int VT, typename InputIt, typename T> MGPU_DEVICE void DeviceGlobalToSharedDefault(int count, InputIt source, int tid, T* dest, T init, bool sync);
Rather than deal with the partial tile in a special branch, our implementations use DeviceGlobalToRegDefault
or DeviceGlobalToSharedDefault
to load any tile-sized intervals—partial tiles are padded with the identity. The same execution code is used on both full and partial tile CTAs.
Both MGPU and CUB encapsulate the storage requirements of a function with the function logic. While encapsulating data and methods (object-oriented programming) is generally not good practice for high-throughput parallel computing, binding storage with methods helps fully utilize on-chip storage.
template<int NT, typename Op = mgpu::plus<int> > struct CTAReduce { typedef typename Op::first_argument_type T; enum { Size = NT, Capacity = NT }; struct Storage { T shared[Capacity]; }; template<int NT, typename Op = mgpu::plus<int> > MGPU_DEVICE static T Reduce(int tid, T x, Storage& storage, Op op = Op()) {
...
Cooperative functions like reduction communicate their shared memory storage requirements by defining a Storage
type in the enclosing class. Storage
provisions space for storing one value per thread. The caller unions this into its own shared memory struct.
typedef CTAReduce<NT> R; typedef CTAScan<NT> S; union Shared { KeyType keys[NT * (VT + 1)]; int indices[NV]; typename R::Storage reduceStorage; typename S::Storage scanStorage; }; __shared__ Shared shared;
Shared memory is a critical resource and many kernels are performance-limited by shared memory capacity. We try to make the most-efficient use of shared memory by unioning together the encapsulated storage objects of each subroutine in the kernel.
As a rule of thumb, don't use shared memory to store data between calls. Use it for dynamic indexing and for inter-thread communication. The device subroutines in this library do not save or restore the contents of shared memory; they simply act as if they have exclusive access to the resource. Calls should not place data into shared memory expecting it to remain unmodified after invoking a device function that takes an encapsulated Storage
parameter.
template<int NT, typename Op = mgpu::plus<int> > struct CTAReduce { typedef typename Op::first_argument_type T; enum { Size = NT, Capacity = NT }; struct Storage { T shared[Capacity]; }; template<int NT, typename Op = mgpu::plus<int> > MGPU_DEVICE static T Reduce(int tid, T x, Storage& storage, Op op = Op()) { storage.shared[tid] = x; __syncthreads(); // Fold the data in half with each pass. #pragma unroll for(int destCount = NT / 2; destCount >= 1; destCount /= 2) { if(tid < destCount) { // Read from the right half and store to the left half. x = op(x, storage.shared[destCount + tid]); storage.shared[tid] = x; } __syncthreads(); } T total = storage.shared[0]; __syncthreads(); return total; } };
CTAReduce::Reduce
iteratively folds pairs of values together until the reduction is complete. Each thread begins by storing its input into shared memory. After the synchronization, we loop over destCount
= NT / 2, NT / 4, ..., 1. At each iteration, thread tid loads the value from destCount + tid
, adds it to its own value, and stores the result at slot tid
. After the loop is complete, all threads load the reduced value and return.
To reduce latency we utilize the shfl
("shuffle") instruction available on Kepler. This feature implements inter-lane communication inside a warp with higher bandwidth than LD/ST pairs to shared memory. Although CUDA C++ includes a __shfl
intrinsic, we choose to access the instruction using inline PTX to save the returned predicate flag. The current CUDA backend copies predicate flags into registers when they are returned as bool
types, resulting in wasted instructions if we were to build a shuffle intrinsic that returned both value and predicate. The best performance is achieved by executing both the shfl and the add in inline PTX.
MGPU_DEVICE int shfl_add(int x, int offset, int width = WARP_SIZE) { int result = 0; #if __CUDA_ARCH__ >= 300 int mask = (WARP_SIZE - width)<< 8; asm( "{.reg .s32 r0;" ".reg .pred p;" "shfl.up.b32 r0|p, %1, %2, %3;" "@p add.s32 r0, r0, %4;" "mov.s32 %0, r0; }" : "=r"(result) : "r"(x), "r"(offset), "r"(mask), "r"(x)); #endif return result; }
The mov
instruction is elided by the compiler, creating a warp scan in a tight sequence of five shfl
and five predicated add
instructions. The shfl_add
function scans multiple segments within a warp, where width
is a power-of-two segment size. The third argument of shfl_add
guards against carry-in from a preceding segment—only values in the same segment are added in each pass.
#if __CUDA_ARCH__ >= 300 template<int NT> struct CTAReduce<NT, mgpu::plus<int> > { typedef mgpu::plus<int> Op; typedef int T; enum { Size = NT, Capacity = WARP_SIZE }; struct Storage { int shared[Capacity]; }; MGPU_DEVICE static int Reduce(int tid, int x, Storage& storage, Op op = Op()) { const int NumSections = WARP_SIZE; const int SecSize = NT / NumSections; int lane = (SecSize - 1) & tid; int sec = tid / SecSize; // In the first phase, threads cooperatively find the reduction within // their segment. The segments are SecSize threads (NT / WARP_SIZE) // wide. #pragma unroll for(int offset = 1; offset < SecSize; offset *= 2) x = shfl_add(x, offset, SecSize); // The last thread in each segment stores the local reduction to shared // memory. if(SecSize - 1 == lane) storage.shared[sec] = x; __syncthreads(); // Reduce the totals of each input segment. The spine is WARP_SIZE // threads wide. if(tid < NumSections) { x = storage.shared[tid]; #pragma unroll for(int offset = 1; offset < NumSections; offset *= 2) x = shfl_add(x, offset, NumSections); storage.shared[tid] = x; } __syncthreads(); int reduction = storage.shared[NumSections - 1]; __syncthreads(); return reduction; } }; #endif // __CUDA_ARCH__ >= 300
We specialize CTAReduce
on the mgpu::plus<int>
operator to accelerate this very common operation. An upsweep is implemented by reducing NumSections = WARP_SIZE
sections, each of width SecSize = NT / WARP_SIZE
. For an eight warp CTA (256 threads), there are NumWarps * log(SecSize) = 24 shfl_add
invocations in the upsweep. The spine scan consists of 5 shfl_add
calls, for 29 in all.
The shfl specialization runs faster than the general case in latency-limited kernels. A CTA with 256 threads requires eight folding passes in the general case, and similarly has a depth of eight shfl_add
calls on warp 0 of the specialization. But in the specialization we replace costly load-store-synchronize sequences with faster shuffles, reducing the time to completion for warp 0.
template<typename Tuning, typename InputIt, typename T, typename Op> MGPU_LAUNCH_BOUNDS void KernelReduce(InputIt data_global, int count, T identity, Op op, T* reduction_global) { typedef MGPU_LAUNCH_PARAMS Params; const int NT = Params::NT; const int VT = Params::VT; const int NV = NT * VT; typedef CTAReduce<NT, Op> R; union Shared { typename R::Storage reduceStorage; }; __shared__ Shared shared; int tid = threadIdx.x; int block = blockIdx.x; int gid = NV * block; int count2 = min(NV, count - gid); // Load a full tile into register in strided order. Set out-of-range values // with identity. T data[VT]; DeviceGlobalToRegDefault<NT, VT>(count2, data_global + gid, tid, data, identity); // Sum elements within each thread. T x; #pragma unroll for(int i = 0; i < VT; ++i) x = i ? op(x, data[i]) : data[i]; // Sum thread-totals over the CTA. x = R::Reduce(tid, x, shared.reduceStorage, op); // Store the tile's reduction to global memory. if(!tid) reduction_global[block] = x; }
This project aims for simplicity, especially in the simplest and earliest algorithms. The implementations of reduce and scan have been heavily revised and simplified from the original version. Each CTA loads one tile of data and emits the reduction of that data. The host function is called recursively until all values have been folded into a single output.
Most MGPU kernels have special logic to deal with the partial tile at the end of each grid. For reduce and scan, however, we opt to simplify the kernel implementation by taking an init
value as an argument. DeviceGlobalToRegDefault
loads a full tile of data in strided order; out-of-range values are filled with init
, which is chosen to be a neutral value when combined with the the reduction operator op
. (Examples are 0 for operator + and 1 for operator *.) Although an identity is not necessary for reduction (it's a minor convenience here), it is necessary for exclusive-scan, and a major convenience for segmented reduction.
After loading a tile of data, each thread folds its VT values into a scalar. Note that adjacent values in the input are not folded together in order; we require the operator be commutative. (i.e. a * b = b * a.) Inputs may be transposed and folded in thread order to support non-commutative operators, although we feel this is rarely, if ever, necessary in practice.
After each thread has reduced its values into x
, the cooperative device subroutine CTAReduce::Reduce
folds values across threads into a tile reduction. The first thread in each CTA stores the reduction to global memory.
template<typename InputIt, typename T, typename Op> MGPU_HOST void Reduce(InputIt data_global, int count, T identity, Op op, T* reduce_global, T* reduce_host, CudaContext& context) { MGPU_MEM(T) totalDevice; if(!reduce_global) { totalDevice = context.Malloc<T>(1); reduce_global = totalDevice->get(); } if(count <= 256) { typedef LaunchBoxVT<256, 1> Tuning; KernelReduce<Tuning><<<1, 256, 0, context.Stream()>>>( data_global, count, identity, op, reduce_global); MGPU_SYNC_CHECK("KernelReduce"); } else if(count <= 768) { typedef LaunchBoxVT<256, 3> Tuning; KernelReduce<Tuning><<<1, 256, 0, context.Stream()>>>( data_global, count, identity, op, reduce_global); MGPU_SYNC_CHECK("KernelReduce"); } else if(count <= 512 * ((sizeof(T) > 4) ? 4 : 8)) { typedef LaunchBoxVT<512, ((sizeof(T) > 4) ? 4 : 8)> Tuning; KernelReduce<Tuning><<<1, 512, 0, context.Stream()>>>( data_global, count, identity, op, reduce_global); MGPU_SYNC_CHECK("KernelReduce"); } else { // Launch a grid and reduce tiles to temporary storage. typedef LaunchBoxVT<256, (sizeof(T) > 4) ? 8 : 16> Tuning; int2 launch = Tuning::GetLaunchParams(context); int NV = launch.x * launch.y; int numBlocks = MGPU_DIV_UP(count, NV); MGPU_MEM(T) reduceDevice = context.Malloc<T>(numBlocks); KernelReduce<Tuning><<<numBlocks, launch.x, 0, context.Stream()>>>( data_global, count, identity, op, reduceDevice->get()); MGPU_SYNC_CHECK("KernelReduce"); Reduce(reduceDevice->get(), numBlocks, identity, op, reduce_global, (T*)0, context); } if(reduce_host) copyDtoH(reduce_host, reduce_global, 1); }
The Reduce
host function is invoked recursively until all inputs fit in a single tile. It returns the reduction in device memory, host memory, or both. Inputs of 256 or fewer elements are processed by a single tile with 256 threads and a grain-size of 1. Inputs of 768 or fewer elements are processed by a single tile with a grain-size of 3. Larger inputs are processed by larger tiles, which register block to increase sequential work per thread and amortize the work-inefficient cooperative CTA reduction.
If multiple CTAs are launched, the tile reductions are stored to the temporary array reduceDevice
, which is fed back into the host Reduce
function. This recursive definition realizes high performance without having to involve "persistent CTAs," a pattern in which a fixed number of CTAs are launched which progressively loop through inputs. Persistant CTAs require occupancy calculation and device knowledge to launch an optimal grid sizes, as well as a fudge factor in the form of oversubscription to smooth out variability in CTA times. Sizing grids to data sizes rather than the number of device SMs keeps code simple: each CTA processes one tile and then exits; the hardware grid scheduler is responsible for load balancing.
template<int NT, typename Op = mgpu::plus<int> > struct CTAScan { typedef typename Op::result_type T; enum { Size = NT, Capacity = 2 * NT + 1 }; struct Storage { T shared[Capacity]; }; MGPU_DEVICE static T Scan(int tid, T x, Storage& storage, T* total, MgpuScanType type = MgpuScanTypeExc, T identity = (T)0, Op op = Op()) { storage.shared[tid] = x; int first = 0; __syncthreads(); #pragma unroll for(int offset = 1; offset < NT; offset += offset) { if(tid >= offset) x = op(storage.shared[first + tid - offset], x); first = NT - first; storage.shared[first + tid] = x; __syncthreads(); } *total = storage.shared[first + NT - 1]; if(MgpuScanTypeExc == type) x = tid ? storage.shared[first + tid - 1] : identity; __syncthreads(); return x; } MGPU_DEVICE static T Scan(int tid, T x, Storage& storage) { T total; return Scan(tid, x, storage, &total, MgpuScanTypeExc, (T)0, Op()); } };
CTAScan
is a basic implementation that uses double buffering to reduce synhronization. The inclusive scan is computed by ping-ponging data between the left and right halves of the storage
buffer each round. If the exclusive scan was requested, each thread returns the preceding thread's inclusive scan value; the first thread returns identity
.
//////////////////////////////////////////////////////////////////////////////// // Special partial specialization for CTAScan<NT, ScanOpAdd> on Kepler. // This uses the shfl intrinsic to reduce scan latency. #if __CUDA_ARCH__ >= 300 template<int NT> struct CTAScan<NT, mgpu::plus<int> > { typedef mgpu::plus<int> Op; enum { Size = NT, NumSegments = WARP_SIZE, SegSize = NT / NumSegments }; enum { Capacity = NumSegments + 1 }; struct Storage { int shared[Capacity + 1]; }; MGPU_DEVICE static int Scan(int tid, int x, Storage& storage, int* total, MgpuScanType type = MgpuScanTypeExc, int identity = 0, Op op = Op()) { // Define WARP_SIZE segments that are NT / WARP_SIZE large. // Each warp makes log(SegSize) shfl_add calls. // The spine makes log(WARP_SIZE) shfl_add calls. int lane = (SegSize - 1) & tid; int segment = tid / SegSize; // Scan each segment using shfl_add. int scan = x; #pragma unroll for(int offset = 1; offset < SegSize; offset *= 2) scan = shfl_add(scan, offset, SegSize); // Store the reduction (last element) of each segment into storage. if(SegSize - 1 == lane) storage.shared[segment] = scan; __syncthreads(); // Warp 0 does a full shfl warp scan on the partials. The total is // stored to shared[NumSegments]. (NumSegments = WARP_SIZE) if(tid < NumSegments) { int y = storage.shared[tid]; int scan = y; #pragma unroll for(int offset = 1; offset < NumSegments; offset *= 2) scan = shfl_add(scan, offset, NumSegments); storage.shared[tid] = scan - y; if(NumSegments - 1 == tid) storage.shared[NumSegments] = scan; } __syncthreads(); // Add the scanned partials back in and convert to exclusive scan. scan += storage.shared[segment]; if(MgpuScanTypeExc == type) { scan -= x; if(identity && !tid) scan = identity; } *total = storage.shared[NumSegments]; __syncthreads(); return scan; } MGPU_DEVICE static int Scan(int tid, int x, Storage& storage) { int total; return Scan(tid, x, storage, &total, MgpuScanTypeExc, 0); } }; #endif // __CUDA_ARCH__ >= 300
The CTA shuffle scan implementation takes the form of warp-synchronous programming but without the need for volatile memory qualifiers. We choose to divide the input into 32 equal segments. For 256 threads, we have a segment size of eight, and this is scanned in three calls to shfl_add
. The last thread in each segment stores the partial sum to shared memory. After a barrier the partials are warp-scanned with five invocations of shfl_add
.
The choice to scan small segments in the upsweep (8 threads/segment) and scan large segments in the spane (32 threads/segment) has significant consequence for work efficiency: in the 256-thread example, each of the eight warps makes three calls to shfl_add
in the upsweep, and the spine warp makes five calls, for 29 shuffles in all. By contrast, setting the segment size to 32 performs a five-pass warp scan in the upsweep and a three-pass scan over the eight partials in the spine, calling shfl_add
43 times. Changing the fan-out of scan networks can have implications for both the latency and efficiency.
template<MgpuScanType Type, typename DataIt, typename T, typename Op, typename DestIt> MGPU_HOST void Scan(DataIt data_global, int count, T identity, Op op, T* reduce_global, T* reduce_host, DestIt dest_global, CudaContext& context) { MGPU_MEM(T) totalDevice; if(reduce_host && !reduce_global) { totalDevice = context.Malloc<T>(1); reduce_global = totalDevice->get(); } if(count <= 256) { typedef LaunchBoxVT<256, 1> Tuning; KernelScanParallel<Tuning, Type><<<1, 256, 0, context.Stream()>>>( data_global, count, identity, op, reduce_global, dest_global); MGPU_SYNC_CHECK("KernelScanParallel"); } else if(count <= 768) { typedef LaunchBoxVT<256, 3> Tuning; KernelScanParallel<Tuning, Type><<<1, 256, 0, context.Stream()>>>( data_global, count, identity, op, reduce_global, dest_global); MGPU_SYNC_CHECK("KernelScanParallel"); } else if (count <= 512 * 5) { typedef LaunchBoxVT<512, 5> Tuning; KernelScanParallel<Tuning, Type><<<1, 512, 0, context.Stream()>>>( data_global, count, identity, op, reduce_global, dest_global); MGPU_SYNC_CHECK("KernelScanParallel"); } else { typedef LaunchBoxVT< 128, (sizeof(T) > 4) ? 7 : 15, 0, 128, 7, 0, 128, 7, 0 > Tuning; int2 launch = Tuning::GetLaunchParams(context); int NV = launch.x * launch.y; int numBlocks = MGPU_DIV_UP(count, NV); MGPU_MEM(T) reduceDevice = context.Malloc<T>(numBlocks + 1); // Reduce tiles into reduceDevice. KernelReduce<Tuning><<<numBlocks, launch.x, 0, context.Stream()>>>( data_global, count, identity, op, reduceDevice->get()); MGPU_SYNC_CHECK("KernelReduce"); // Recurse to scan the reductions. Scan<MgpuScanTypeExc>(reduceDevice->get(), numBlocks, identity, op, reduce_global, (T*)0, reduceDevice->get(), context); // Add scanned reductions back into output and scan. KernelScanDownsweep<Tuning, Type> <<<numBlocks, launch.x, 0, context.Stream()>>>(data_global, count, reduceDevice->get(), identity, op, dest_global); MGPU_SYNC_CHECK("KernelScanDownsweep"); } if(reduce_host) copyDtoH(reduce_host, reduce_global, 1); }
The MGPU Scan implementation executes a reduction in its upsweep to compute carry-in for downsweep scan. We reuse KernelReduce
to compute per-tile reductions. The tile reductions are then recursively fed back into the Scan
host function. On return, KernelScanDownsweep
loads complete tiles from the input, scans them locally, and adds-in the scanned upsweep reductions as carry-in.
Launching kernels on very small inputs doesn't do much work but may still contribute a lot of latency to the pipeline, because the entire queue will wait for a single CTA to finish. We implement a simple intra-tile scan that runs on a singcle CTA and size the launch for shallow and wide kernels, based on input size, to minimize latency. This is the spine scan of our upsweep-spine-downsweep pattern.


| interfacesAttribute {Rcpp} | R Documentation |
The Rcpp::interfaces
attribute is added to a C++ source file to specify which languages to generate bindings for from exported functions. For example:
// [[Rcpp::interfaces(r, cpp)]]
... |
Interfaces to generate for exported functions within the source file. Valid values are |
The Rcpp::interfaces
attribute is used to determine which bindings to generate for exported functions. The default behavior if no Rcpp::interfaces
attribute is specified is to generate only an R interface.
When cpp
bindings are requested code is generated as follows:
Bindings are generated into a header file located in the inst/include
directory of the package using the naming convention PackageName_RcppExports.h
If not already present, an additional header file named PackageName.h is also generated which in turn includes the Rcpp exports header.
In the case that you already have a PackageName.h header for your package then you can manually add an include of the Rcpp exports header to it to make the exported functions available to users of your package.
The generated header file allows calling the exported C++ functions without any linking dependency on the package (this is based on using the R_RegisterCCallable
and R_GetCCallable
functions).
The exported functions are defined within a C++ namespace that matches the name of the package.
For example, an exported C++ function foo
could be called from package MyPackage
as follows:
// [[Rcpp::depends(MyPackage)]] #include <MyPackage.h> void foo() { MyPackage::bar(); }
The above example assumes that the sourceCpp
function will be used to compile the code. If rather than that you are building a package then you don't need to include the Rcpp::depends
attribute, but instead should add an entry for the referenced package in the Depends
and LinkingTo
fields of your package's DESCRIPTION
file.
If a file by the name of PackageName.h that wasn't generated by compileAttributes
already exists in in the inst/include
directory then it will not be overwritten (rather, an error will occur).
A static naming scheme for generated header files and namespaces is used to ensure consistent usage semantics for clients of exported cpp
interfaces. Packages that wish to export more complex interfaces or additional C++ types are therefore typically better off not using this mechanism.
The Rcpp::interfaces
attribute is specified using a syntax compatible with the new generalized attributes feature of the C++11 standard. Note however that since this feature is not yet broadly supported by compilers it needs to be specified within a comment (see examples below).
compileAttributes
, Rcpp::export
, Rcpp::depends
## Not run: // [[Rcpp::interfaces(r, cpp)]] ## End(Not run)


Nicolas Cage looks set to play Nicolas Cage in bonkers new meta movie
Please let it happen
Nicolas Cage looks set to star as himself in an upcoming meta movie titled The Unbearable Weight of Massive Talent.
The acting legend, who’s starred in films such as Face/Off, Con Air, The Wicker Man and many more, will reportedly play a fictional version of Nic Cage who attempts to land a role in a Quentin Tarantino movie after his career takes a turn for the worst.
According to The Hollywood Reporter, production company Lionsgate is in final talks to pick up the project which is said to have been written by Tom Gormican and Kevin Etten. Gormican will also take on directing duties, the outlet claims.
Nicolas Cage outside Universal Studios, 1997
Facing financial difficulties, the fictional Nic Cage agrees to pen a script for a billionaire member of the Mexican drug cartel. He then becomes a CIA operative tasked with rescuing a presidential candidate’s child, who’s been kidnapped by the drug kingpin.
Throughout the film, the character – who struggles with a strained relationship with his daughter – also speaks to an egotistical and more successful version of himself from the ’90s.
Reports state that Cage signed up after bosses wrote to him insisting that The Unbearable Weight of Massive Talent was a love letter to his whirlwind career, rather than a spoof.
Lionsgate are yet to confirm the project.
Meanwhile, Nicolas Cage has responded to online calls for him to play Superman – explaining that he’d much rather take on the role of a villain.


Sri Lanka: Mahinda Rajapaksa to be sworn in as PM today
Leaders of the parties that backed Gotabaya during the presidential polls will be given preference in the Cabinet.
by ANIColombo: Sri Lanka's newly elected President Gotabaya Rajapaksa's brother Mahinda Rajapaksa will be sworn in as the new prime minister of the island nation on Wednesday.
Mahinda Rajapaksa has served as president from 2005 to 2015. The way for his accession was paved after Ranil Wickremesinghe announced his resignation to allow the new President Gotabaya Rajapaksa to form a caretaker government. Wickremesinghe took the decision after a special cabinet meeting on Wednesday a day after he met Gotabaya and discussed the matter.
The President has reportedly decided to appoint a caretaker cabinet with 15 members until the General Elections which can be held in March 2020 after dissolving the current parliament according to the constitution, Colombo Page reported.
Leaders of the parties that backed Gotabaya during the presidential polls will be given preference in the Cabinet.
The Rajapaksa brothers are credited with crushing the Tamil Tigers a decade ago to end Sri Lanka's civil war, with the security services they controlled accused of war crimes and multiple human rights abuses.
Catch the latest news, live coverage and in-depth analyses from India and World. Follow us on Facebook and Twitter.


Balance Graph
Inflows & Outflows Dynamic
Home
Visualisations
Accounts to be Collected
Accounts to be Paid
Map
New JS library
____________________________________


|
My Project
|
Used to define visitor-pattern functionality for graphics_commands. More...
#include <graphics_visitor.hpp>
Public Member Functions | |
| virtual | ~graphics_visitor ()=default |
| virtual void | visit (clear_command &cmd)=0 |
| virtual void | visit (draw_command &cmd)=0 |
| virtual void | visit (viewport_command &cmd)=0 |
| virtual void | visit (scissor_command &cmd)=0 |
| virtual void | visit (fill_vertex_buffer_command &cmd)=0 |
| virtual void | visit (fill_index_buffer_command &cmd)=0 |
| virtual void | visit (frame_buffer_command &cmd)=0 |
| virtual void | visit (frame_buffer_texture_command &cmd)=0 |
| virtual void | visit (generate_mipmaps_command &cmd)=0 |
| virtual void | visit (set_material_parameters_command &cmd)=0 |
Used to define visitor-pattern functionality for graphics_commands.
|
virtualdefault |
|
pure virtual |
|
pure virtual |
|
pure virtual |
|
pure virtual |
|
pure virtual |
|
pure virtual |
|
pure virtual |
|
pure virtual |
|
pure virtual |
|
pure virtual |


BWB is easy to use. You just need to add the following code to use BWB. (Do you know this website was also built by BWB?)
Add them to prevent the unknown errors!


Day 29
For broken families
29
This day, along with my brothers and sisters in Christ, I intercede for the families that are broken by sin and the deceptions of the evil one. Bring healing and reconciliation to families. Heal our nation’s families, we cry. Turn the hearts of families to realize that You are the answer, and that it is You alone who can heal and save. Raise up family ministries in Your churches. Strengthen the para-church ministries that minster to families.You alone, O’ Lord, know the brokenness and the true cause of the brokenness. Man doesn’t know the heart, only the Spirit of God knows and discerns what truly lies within the depths of a man’s heart. We ask that somehow, some way, that You would bring healing and reconciliation to the homes of our communities and of this nation.
We also interceded on behalf of the spouses and children and parents who are being abused and neglected. Rescue them, Jesus. Heal them from their wounds, trauma, and scars. And fill them with Your everlasting love.
Show us, Muddy Creek Baptist Church, as You show me personally, what we can do to minister to broken and hurting families. Here I am, Lord; here we are, Lord, use us. Amen. (I Peter 3:7; 4:8; Exodus 20:12; Psalm 127:3-5; 147:3; Joshua 24:15; Proverbs 11:29; Colossians 3:18-21)


I am a Full Stack Developer with a drive to use my skills for problem solving, product improvement, and the betterment of people and society. My experience in quality control and program delivery for a patient-focused non-profit has cultivated my strong desire to improve communication and outcomes for customers. Empathy, emotional intelligence, and creativity are integral to who I strive to be inside and outside of the workplace.
Many things aside from technology have contributed to my love of creating stylish and innovative products. My love for film, art, and the outdoors informs my appreciation of aesthetics. My years as a musician and motorcyclist has taught me how to be a student and a tinkerer. My new deep interest in exploring culinary traditions around the world has taught me when to follow a recipe and when to innovate.


pymerkle.nodes module¶
Provides the base class for the Merkle-tree’s nodes and an inheriting class for its leaves
-
class
pymerkle.nodes.
leaf
(record, hashfunc, encoding)[source]¶ Bases:
pymerkle.nodes.node
Class for the leafs of Merkle-tree (parentless nodes)
Parameters: - record (str or bytes or bytearray) – the record to be encrypted within the leaf
- hashfunc (method) – hash function to be used for encryption (only once). Should be the
.hash
attribute of the containing Merkle-tree - encoding (str) – Encoding type to be used when decoding the hash stored by the node. Should coincide with the containing Merkle-tree’s encoding type.
-
class
pymerkle.nodes.
node
(hashfunc, encoding, record=None, left=None, right=None)[source]¶ Bases:
object
Base class for the nodes of a Merkle-tree
Parameters: - record (str or bytes or bytearray) – [optional] the record to be encrypted within the node. If provided, then the node is considered to be a leaf
- left (nodes.node) – [optional] the node’s left parent. If not provided, then the node is considered to be a leaf
- right (nodes.node) – [optional] the node’s right parent. If not provided, then the node is considered to be a leaf
- hashfunc (method) – hash function to be used for encryption. Should be the
.hash
method of the containing Merkle-tree - encoding (str) – Encoding type to be used when decoding the hash stored by the node. Should coincide with the containing Merkle-tree’s encoding type.
Variables: - digest – (bytes) The hash currently stored by the node
- left – (nodes.node) The node’s left parent. Defaults to
None
if the node is a leaf - right – (nodes.node) The node’s right parent. Defaults to
None
if the node is a leaf - child – (nodes.node) The node’s child parent. Defaults to
None
if the node is a root - hashfunc – (method) The hash function used by the node when recalcullating hashes. For interior nodes
it should coincide with the
.hash
attribute of the containing Merkle-tree. For leaf nodes it isNone
, since their hash is never recalculated. - encoding – (str) Used by the node for decoding its hash. Should coincide with the encoding type of the containing Merkle-tree.
-
JSONstring
()[source]¶ Returns a nicely stringified version of the node’s JSON serialized form
Note
The output of this function is to be passed into the
print
functionReturn type: str
-
descendant
(degree)[source]¶ Detects and returns the node that is
degree
steps upwards within the containing Merkle-treeNote
Descendant of degree
0
is the node itself, descendant of degree1
is the node’s child, etc.Parameters: degree (int) – depth of descendancy. Must be non-negative Returns: the descendant corresdponding to the requested depth Return type: nodes.node Note
Returns
None
if the requested depth of dependancy exceeds possibilities
-
is_left_parent
()[source]¶ Checks if the node is a left parent
Returns: True
iff the node is the.left
attribute of some other node inside the containing Merkle-treeReturn type: bool
-
is_right_parent
()[source]¶ Checks if the node is a right parent
Returns: True
iff the node is the.right
attribute of some other node inside the containing Merkle-treeReturn type: bool
-
recalculate_hash
()[source]¶ Recalculates the node’s hash under account of its parents’ new hashes
This method is to be invoked for all non-leaf nodes of the Merkle-tree’s rightmost branch every time a new leaf is appended into the tree
Warning
Only for interior nodes (i.e., with two parents); fails in case of leaf nodes
-
class
pymerkle.nodes.
nodeEncoder
(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)[source]¶ Bases:
json.encoder.JSONEncoder
Used implicitly in the JSON serialization of nodes. Extends the built-in JSON encoder for data structures.


@* * Copyright 2021 HM Revenue & Customs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *@ @import playconfig.FormPartialProvider @()(implicit request: Request[_], messages: Messages)


Digital India is a flagship programme of the Government of India with a vision
to transform India
into a digitally empowered society and knowledge economy. Digital India is an umbrella
programme that covers
multiple Government Ministries and Departments. It weaves together a large number of ideas and thoughts into
a
single, comprehensive vision so that each of them can be implemented as part of a larger goal.
Each individual element stands on its own, but is also part of the larger picture. Digital
India is to be
implemented by the entire Government with overall coordination being done by the Department of Electronics
and
Information Technology (DeitY).
Digital India aims to provide the much needed thrust to the nine pillars of growth areas,
namely Broadband
Highways, Universal Access to Mobile Connectivity, Public Internet Access Programme, e-Governance: Reforming
Government through Technology, e-Kranti - Electronic Delivery of Services, Information for All, Electronics
Manufacturing, IT for Jobs and Early Harvest Programmes. Each of these areas is a complex programme in
itself and cuts across multiple Ministries and Departments.
Launched on 1 July 2015, by Indian Prime Minister Narendra Modi, it is both enabler and beneficiary of other
key Government of India schemes, such as BharatNet, Make in India, Startup India and Standup India,
industrial corridors, Bharatmala, Sagarmala.
As of 31 December 2018, India had a population of 130 crore people (1.3 billion), 123
crore (1.23 billion)
Aadhaar digital biometric identity cards, 121 crore (1.21 billion) mobile phones, 44.6
crore (446 million)
smartphones, 56 crore (560 million) internet users up from 481 million people (35% of the
country's total
population) in December 2017, and 51 per cent growth in e-commerce.


Echo Wang
This site is temporarily down for maintenance (˃̣̣̥⌓˂̣̣̥⋆)
But you can scroll down to check out some of my projects in the meantime!


Navbar
Home
(current)
Features
Pricing
Dropdown
Action
Another action
Something else here
Material Design for Bootstrap 4
The most powerful and free UI KIT for Bootstrap
Sign up!
Learn more


selectr demo
Turn ordinary select boxes into these neat guys
Multi-select
Bacon (Extra long name foo bar baz quz)
Eggs
Toast
Oatmeal
Steak
Sausage
Fresh Fruit
Single-select
Coffee
Milk
Juice (no color coding)


Knowledge space theory by Doignon and Falmagne (1999) <doi:10.1007/978-3-642-58625-5> is a set- and order-theoretical framework which proposes mathematical formalisms to operationalize knowledge structures in a particular domain. The 'kstIO' package provides basic functionalities to read and write KST data from/to files to be used together with the 'kst', 'kstMatrix', 'pks' or 'DAKS' packages.
| Version: | 0.2-0 |
| Depends: | R (≥ 3.3.0), pks (≥ 0.4-0), MASS, stringr, sets |
| Suggests: | kst (≥ 0.3-0) |
| Published: | 2018-09-11 |
| Author: | Cord Hockemeyer [aut, cre] |
| Maintainer: | Cord Hockemeyer <cord.hockemeyer at uni-graz.at> |
| License: | GPL (≥ 3) |
| NeedsCompilation: | no |
| Materials: | ChangeLog |
| CRAN checks: | kstIO results |
| Reference manual: | kstIO.pdf |
| Vignettes: |
KSTIO |
| Package source: | kstIO_0.2-0.tar.gz |
| Windows binaries: | r-devel: kstIO_0.2-0.zip, r-release: kstIO_0.2-0.zip, r-oldrel: kstIO_0.2-0.zip |
| OS X binaries: | r-release: kstIO_0.2-0.tgz, r-oldrel: kstIO_0.2-0.tgz |
| Old sources: | kstIO archive |
Please use the canonical form https://CRAN.R-project.org/package=kstIO to link to this page.