Spuštění aplikace na platformě JAVA

Z MetaCentrum
Skočit na navigaci Skočit na vyhledávání

(English version)


Metacentrum wiki is deprecated after March 2023
Dear users, due to integration of Metacentrum into https://www.e-infra.cz/en (e-INFRA CZ service), the documentation for users will change format and site.
The current wiki pages won't be updated after end of March 2023. They will, however, be kept for a few months for backwards reference.
The new documentation resides at https://docs.metacentrum.cz.

Pro spouštění programů na platformě Java použijte aplikaci JDK.

Paralelizace v Javě

Žádná paralelizace

Pokud ve svém programu v Javě nespouštíte nová vlákna, veškerá práce probíhá v jednom vláknu jménem main, a paralelizaci nemusíte řešit.

Pokud používáte cizí program, nemáte obvykle moc kontrolu nad tím, kolik vláken používá, požádejte proto o celý stroj pomocí #excl, viz jak žádat zdroje.

Paralelizace vlákny

Platforma Java umožňuje snadno využít paralelní práci na více procesorech nad sdílenou pamětí jednoho stroje pomocí tzv. vláken.

Pokud potřebujte úvod do programování vláken v Javě, zkuste The Java Tutorials - Lesson: Concurrency.

V prostředí MetaCentra je důležité si uvědomit, že na jednom stroji můžou běžet úlohy více uživatelů, a každý z nich by měl využít nanejvýš ty zdroje, které má přiděleny. U vlastních programů v Javě můžete poměrně přesně ovlivnit, kolik vláken běží současně, zajistěte proto, že jich nespustíte více, než kolik má vaše úloha přiděleno procesorů.

Celkový počet CPU stroje v Javě zjistíte voláním metody Runtime.availableProcessors().

Pokud však nepožádáte o celý stroj pomocí #excl, můžete použít jen vyhrazený počet.

Využití nanejvýš n vláken zajistíte nejlépe pomocí metody Executors.newFixedThreadPool(int), tak jak je popsáno v tutoriálu Thread Pools.

Příklad programu využívajícího specifikovaný počet vláken:

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;

public class Exekuce {

    static public class Producer implements Callable<String> {

        private final int n;

        public Producer(int n) {
            this.n = n;
        }

        public String call() throws Exception {
            //vlastní náročný výpočet
            return " Product("+n+")";
        }
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        //počet vláken podle parametru nebo pokud není, tak podle počtu CPU
        int numThreads = Runtime.getRuntime().availableProcessors();
        if(args.length>0) {
            numThreads = Integer.parseInt(args[0]);
        }
        
        //pool vláken specifikované velikosti
        ExecutorService executorService = Executors.newFixedThreadPool(numThreads);

        //zpracovatelé
        List<Producer> producers = Arrays.asList(new Producer(1), new Producer(2), new Producer(3));

        //paralelní  zpracování
        List<Future<String>> futures = executorService.invokeAll(producers);
        executorService.shutdown();

        //získání výsledků
        for (Future<String> fs : futures) {
            System.out.println("výsledek " + fs.get());
        }

    }

Spuštění Java programu

Přihlašte se na některý čelní uzel kromě skiritu, kde je omezení na paměť, třeba minos, kde si připravíte program.

ssh minos.metacentrum.cz

Java kód

Program si připravte v některém adresáři viditelném na všech strojích, třeba v /storage/brno2/home/$LOGNAME.

HelloWorld.java

    public class HelloWorld {
        public static void main(String args[]) {
            System.out.println("Hello world " + args[0]);
        }
    }

přidejte si na čelním uzlu JDK pomocí

module add jdk-7

a přeložte program pomocí příkazu

javac HelloWorld.java

do souboru HelloWorld.class.

Spouštěcí skript

Modul jdk-7 poskytuje celý Java Development Kit (JDK), tedy i Java Runtime Environment (JRE) ve formě příkazu java.

Skript pro spuštění úlohy musí inicializovat modul s JDK na výpočetním uzlu a pak spustit program v Javě:

task.sh

#!/bin/bash

# inicializace konkretni verze JAVA
module add jdk-7

java -cp /storage/brno2/home/$LOGNAME HelloWorld ahoj

Zadání úlohy

Úlohu zadáte z čelního uzlu pomocí příkazu

qsub -q short -l nodes=1:ppn=1:nfs4,mem=1gb -j oe -m e task.sh

Po doběhnutí úlohy jednak dostanete e-mail (nastaveno pomocí -m e) a druhak v adresáři, ze kterého jste spustili příkaz qsub, bude soubor s názvem task.sh.oNNNNNN (kde NNNNN bude číslo úlohy) obsahující výstup z úlohy.

Práce s daty

U Java programů platí samozřejmě pro práci s daty stejná pravidla jako u ostatních programů, viz kapitola Práce s daty.

Zejména nepoužívejte pro zápis většího množství dat standardní výstup, ale zapisujte do souboru na lokálním disku v adresáři určeném proměnou $SCRATCHDIR, a po skončení výpočtu data přeneste pryč.