toUpperCase

This application demonstrates how to turn lowercase characters into uppercase characters using the Distributive 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: 'passphrase' }];
    
  7. Await the resultSet: Execute the job in parallel on DCP via

    resultSet = await job.exec();
    

A plain web 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 it this example helps show DCP-specific code without worrying about application details.

Setup

First, set up an HTML file. Requiring the dcp-client library in the first script tag allows the app to distribute work. Some pre-written HTML displays the output, but the rest of the tutorial is in JavaScript within the second script tag.

<!doctype html>
<html>
  <head>
    <script src="https://scheduler.distributed.computer/dcp-client/dcp-client.js"></script>
    <script>
      // The rest of our code will go here!
    </script>
  </head>
  <body>
    <p>
      Input string:
      <input type="text" id="input-string" value="hello distributed world!" />
    </p>
    <input type="button" id="deploy" value="Deploy" onclick="deploy()" />
    <p>Output: <span id="output"></span></p>
  </body>
</html>

Input data

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

/* INPUT SET */
function generateInputSet(string) {
  return Array.from(string);
}

Work function

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

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

Compute for

Now set up the DCP job. The function deploy() launches the job using the compute.for() statement. DCP sends each value from the inputSet to a sandbox. A sandbox is a clean environment on your Worker that runs your work function.

async function deploy() {
  // Some application-specific, HTML set up.  Not super important to DCP
  const inputString = document.getElementById('input-string').value;
  const inputSet = generateInputSet(inputString);

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

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 */
const resultSet = await job.exec();
const output = Array.from(resultSet).join('');
document.getElementById('output').appendChild(document.createTextNode(output));

Run it

Open your HTML file in a web browser, and press deploy.

Full code

Click to see full code.
<!doctype html>
<html>
  <head>
    <script src="https://scheduler.distributed.computer/dcp-client/dcp-client.js"></script>
    <script>
      /* INPUT SET */
      function generateInputSet(string) {
        return Array.from(string);
      }

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

      async function deploy() {
        const inputString = document.getElementById('input-string').value;
        const inputSet = generateInputSet(inputString);

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

        // SKIP IF: you do not need a Compute Group (optional)
        job.computeGroups = [{ joinKey: 'demo', joinSecret: 'dcp' }];

        // DEV: report results as they come in (optional)
        job.on('result', (ev) => {
          console.log(` - Received result ${ev}`);
        });

        /* PROCESS RESULTS */
        const resultSet = await job.exec();
        const output = Array.from(resultSet).join('');
        document
          .getElementById('output')
          .appendChild(document.createTextNode(output));
        console.log(' - Job Complete');
      }
    </script>
  </head>
  <body>
    <p>
      Input string:
      <input type="text" id="input-string" value="hello distributed world!" />
    </p>
    <input type="button" id="deploy" value="Deploy" onclick="deploy()" />
    <p>Output: <span id="output"></span></p>
  </body>
</html>