toUpperCase

This application demonstrates how to turn lowercase characters into uppercase characters using the Distributed Compute Protocol (DCP). If you have a good understanding of how DCP works and the terminology already please feel free to skip the refresher and jump straight to the set up.

A refresher

Click to see the refresher

DCP is a distributed computing framework made from web-based technology.

Computers and devices in classrooms, computer labs, households, and enterprises can be turned into computing clusters with a single click with DCP. The computational workload, a job, is sub-divided into smaller parts. These smaller parts are called slices. Slices are executed in parallel using DCP. Each slice of the job will correspond to a value in an array that we wish to make uppercase. Slices will be sent to different Workers (for example, laptops, desktops, cell phones, etc.) which contain sandboxes. A sandbox is a clean environment on your Worker that runs your work function.

DCP is a powerful parallel computing framework that allows users to express a computational job as effortlessly as: job = compute.for(inputSet, workFunction)

resultSet = await job.exec()

A workFunction is mapped onto each element in an inputSet. Each mapping represents a slice. Slices are distributed across DCP networks for computation. Results are returned to the user from DCP networks coherently.

Remember, the work function must contain progress();. Progress is a call made to tell the scheduler that the job is still alive and running. Progress is considered the heart beat of the job, without it the job would die and no results would be returned.

  1. Create compute nodes: go to https://dcp.work on as many devices as you want and click Start to join the public compute group, or to dcp.work/joinKey if you have a private compute group joinKey and joinSecret.

  2. Configure dev environment: load dcp-client and any required packages.

  3. Specify the inputSet: an arbitrary, but enumerable input dataset (parameters, mp3 files, images, blender project file, etc)

  4. Specify the workFunction: an arbitrary work function (physics simulation, inference model, rendering process, etc)

  5. Express the job: Map the workFunction onto the inputSet with job = compute.for(inputSet, workFunction)

  6. (optional) Specify a compute group with job.computeGroups=[{joinKey: name, joinSecret: password}]

  7. Await the resultSet: Execute the job in parallel on DCP via resultSet = await job.exec()

A plain node example of using distributed computing to capitalize a string:

First, sign up for a DCP account at https://portal.distributed.computer. After signing up, download the id.keystore and default.keystore associated with your account. Refer to this tutorial for more information on how to download your keystores.

In this example, the DCP app takes a string and splits it into characters. Each character is sent to a Worker who capitalizes it, and reports the results. You typically wouldn’t distribute such a small task, but this example helps show DCP-specific code without worrying about application details.

Setup

Create a directory for your project, and download the DCP packages by running the below command.

npm i dcp-client

Next, make a JavaScript file and create the asynchronous main function. The program requires the dcp-client module to initialize access to the Compute API.

async function main() {
  const compute = require('dcp/compute');
  // Rest of the code will go in the following sections:
  /* INPUT DATA */

  /* WORK FUNCTION */

  /* COMPUTE FOR */

  /* PROCESS RESULTS */
}
require('dcp-client').init('https://scheduler.distributed.computer').then(main);

Input data

In this example, the input set is an array of characters, taken from the input string "yelling!".

/* INPUT SET */
const inputSet = Array.from('yelling!');

Work function

The work function is what each Worker runs. In this case, each Worker takes one input character, and turns it to upper case.

/* WORK FUNCTION */
async function workFunction(letter) {
  progress();
  return letter.toUpperCase();
}

Compute for

Now set up the DCP job. DCP sends each value from the inputSet to a sandbox. A sandbox is a clean environment on your Worker that runs your work function. The work function capitalizes every value in the inputSet.

/* COMPUTE FOR */
const job = compute.for(inputSet, workFunction);
job.public.name = 'toUpperCase';

Compute group

If you don’t need a compute group, skip this section. If you do, enter this line with the key information to join that group.

// SKIP IF: you do not need a compute group
job.computeGroups = [{ joinKey: 'Your Key', joinSecret: 'Your Key' }];

Process results

Next, await the results. The result is an array of capitalized characters. Put the capitalized characters back into one string and print them.

/* PROCESS RESULTS */
let resultSet = await job.exec();
resultSet = Array.from(resultSet);
console.log(resultSet.toString().replace(',', ''));

Run it

Run node your-file.js, and watch as your work distributes.

Full code

Click to see full code.
async function main() {
  const compute = require('dcp/compute');

  /* INPUT SET */
  const inputSet = Array.from('yelling!');

  /* WORK FUNCTION */
  async function workFunction(letter) {
    progress();
    return letter.toUpperCase();
  }

  /* COMPUTE FOR */
  const job = compute.for(inputSet, workFunction);
  job.public.name = 'toUpperCompute';

  // SKIP IF: you do not need a compute group
  // job.computeGroups = [{ joinKey: 'KEY', joinSecret: 'SECRET' }];

  // Not mandatory console logs for status updates
  job.on('accepted', () => {
    console.log(` - Job accepted with id: ${job.id}`);
  });
  job.on('result', (ev) => {
    console.log(` - Received result ${ev}`);
  });

  /* PROCESS RESULTS */
  let resultSet = await job.exec();
  resultSet = Array.from(resultSet);
  console.log(resultSet.toString().replace(',', ''));
  console.log(' - Job Complete');
}
require('dcp-client').init('https://scheduler.distributed.computer').then(main);