Page tree
Skip to end of metadata
Go to start of metadata

Krótki opis usługi

Usługa QCG-Vis jest usługą zdalnej wizualizacji typu in-situ, która oferuje możliwość rozproszonej analizy i wizualizacji danych jednocześnie z obliczeniami, a także na sterowanie obliczeniami z poziomu aplikacji do wizualizacji po stronie użytkownika.

Aktywowanie usługi

Aby skorzystać z usługi należy mieć konto w projekcie PL-Grid (Rejestracja).

Po założeniu konta w portalu PLGrid konieczna jest aktywacja usługi QCG-Vis w portalu. W tym celu należy:

  1. Zalogować się w portalu PLGrid (https://portal.plgrid.pl).
  2. Przejść do zakładki "Moje konto".
  3. Po prawej stronie ekranu, w sekcji "Katalog Usług", odnaleźć grupę "Usługi wizualizacji" (w razie potrzeby kliknąć "rozwiń").
  4. Następnie w kolumnie "Status" przy usłudze QCG-Vis kliknąć odnośnik "Aplikuj o usługę".
    Status powinien zmienić się na "Zgłoszono wniosek". 
    Po włączeniu usługi, zostanie przesłane powiadomienie na adres e-mail.

Ponadto, wymagane jest zaaplikowanie o usługę ogólną QCG (Aplikowanie o dostęp do usług QCG), oraz poprawnie skonfigurowany QCG-Icon, który wykorzystywany jest do zlecania wybranych zadań do infrastruktury gridowej.

Niezbędna jest również instalacja wybranych komponentów po stronie użytkownika, szczegóły opisano poniżej.

Ograniczenia w korzystaniu

  • Usługa wizualizacji QCG-Vis dostępna jest wyłącznie na maszynie moss.man.poznan.pl, tam też należy zlecać zadania wizualizacji. 
  • Aplikacje obliczeniowe in-situ mogą być uruchomione na dowolnej maszynie PLGrid, jednak na chwilę obecną stosowne biblioteki są zainstalowane na inula.man.poznan.pl
  • Wymagania względem aplikacji obliczeniowej:
    • Język programowania C/C++ lub Fortran
    • Zrównoleglenie MPI
    • Dane wynikowe w formacie HDF5

Pierwsze kroki

W celu skorzystania z usługi QCG-Vis należy zainstalować na komputerze osobistym niezbędne oprogramowanie, m.in. aplikację do wizualizacji, a także przystosować aplikację obliczeniową do współpracy z usługa. Poniżej znajduje się szczegółowy opis instalacji, przygotowania aplikacji oraz korzystania z usługi.

Instalacja niezbędnych komponentów po stronie użytkownika

W celu skorzystania z usługi QCG-Vis użytkownik musi zainstalować odpowiednią wersje aplikacji do wizualizacji ParaView, wraz z niezbędnymi rozszerzeniami.


Ważna uwaga

W przypadku wykorzystania kompilatorów (C, C++, Fortran - wszystkie komponenty klienckie) oraz bibliotek MPI (hdf5-vfd, h5fddsm, paraview), które nie są domyślnymi w systemie lub nie zostały przez system znalezione, należy uwzględnić ustawiając wartości odpowiednich zmiennych CMAKE.

 

CMAKE_C_COMPILER sciezka_do_kompilatora_C
CMAKE_CXX_COMPILER sciezka_do_kompilatora_CXX
CMAKE_Fortran_COMPILER sciezka_do_kompilatora_fortran
MPI_CXX_COMPILER sciezka_do_kompilatora_mpicxx
MPI_C_COMPILER sciezka_do_kompilatora_mpicc
MPI_CXX_LIBRARIES biblioteki_kompilatora_mpicxx
MPI_C_LIBRARIES biblioteki_kompilatora_mpic
MPI_CXX_INCLUDE_PATH katalog_plikow_naglowkowych_kompilatora_mpicxx
MPI_C_INCLUDE_PATH katalog_plikow_naglowkowych_kompilatora_mpic
MPI_Fortran_COMPILER sciezka_do_kompilatora_mpifortran 
 


HDF5-VFD

Usługa QCG-Vis operuje jedynie na danych HDF5 (i pochodnych). W tym celu należy zainstalować jedną z ostatnich wersji HDF5-VFD. 

Natywny HDF5 od wersji 1.9 będzie zawierał wszelkie modyfikacje niezbędne do poprawnej pracy usługi QCG-Vis.

Należy pobrać kod źródłowy HDF5-VFD 1.8.9 i przystąpić do instalacji:

Przygotowanie do kompilacji
tar -xzf hdf5-vfd-1.8.9.tgz
cd hdf5-vfd-1.8.9
mkdir build
cd build
ccmake ..
Parametry kompilacji
BUILD_SHARED_LIBS				 ON
BUILD_TESTING					 OFF
CMAKE_INSTALL_PREFIX             /ścieżka/instalacji
CMAKE_BUILD_TYPE				 RELEASE
HDF5_BUILD_CPP_LIB               OFF
HDF5_BUILD_FORTRAN               ON
HDF5_BUILD_HL_LIB                ON
HDF5_BUILD_TOOLS                 ON
HDF5_ENABLE_HSIZET               ON
HDF5_ENABLE_LARGE_FILE           ON
HDF5_ENABLE_PARALLEL             ON
HDF5_ENABLE_Z_LIB_SUPPORT        ON
ZLIB_INCLUDE_DIR                 ścieżka_do_plików_nagłówkowych_biblioteki_ZLIB   
ZLIB_LIBRARY                     ścieżka_do_biblioteki_ZLIB
Kompilacja i instalacja
make && make install

 

H5FDdsm

Pakiet H5FDdsm jest dodatkiem do HDF5, który umożliwia równoległą komunikację do transferu danych pomiędzy aplikacjami. Po pobraniu kodu źródłowego H5FDdsm 0.9.9 należy go skompilować i zainstalować.

Przygotowanie do instalacji
tar -xzf h5fddsm-0.9.9.tgz
cd h5fddsm-0.9.9-git
mkdir build
cd build
ccmake ..
Parametry kompilacji
BUILD_SHARED_LIBS			 ON
CMAKE_BUILD_TYPE			 Release
CMAKE_INSTALL_PREFIX         /ścieżka/instalacji
H5FDdsm_BUILD_FORTRAN        ON                                           
H5FDdsm_BUILD_STEERING       ON     
H5FDdsm_BUILD_TOOLS          ON
QCG_VIS_ENABLE				 ON                                                               
HDF5_DIR                     /ścieżka/do/hdf5-vfd//share/cmake/hdf5 
HDF5_INCLUDE_DIRS            /ścieżka/do/hdf5-vfd/include
QCG_VIS_DEBUG				 ON (jeśli chcemy włączyć komunikaty typu DEBUG)
LibCURL_INCLUDE_DIR          ścieżka_do_plików_nagłówkowych_biblioteki_libcurl
LibCURL_LIBRARIES            biblioteka_libcurl
Kompilacja oraz instalacja
make && make install

 

ParaView

QCG-Vis wymaga posługiwania się specjalną wersją ParaView, przystosowaną do wizualizacji typu in-situ. Należy pobrać wersję ParaView QCG-Vis 3.14.1 i odpowiednio zainstalować.

Przygotowanie do kompilacji
tar -xzf paraview-3.14.1-qcg-vis.tgz
cd paraview-3.14.1-qcg-vis
mkdir build
cd build
ccmake ..
Parametry kompilacji
BUILD_EXAMPLES              		OFF
BUILD_SHARED_LIBS           		ON
BUILD_TESTING               		OFF
CMAKE_BUILD_TYPE					Release
CMAKE_INSTALL_PREFIX        		/ścieżka/instalacji
H5FDdsm_DIR                 		/ścieżka/do/h5fddsm/share/cmake/h5fddsm
HDF5_DIR                    		/ścieżka/do/hdf5-vfd/share/cmake/hdf5
HDF5_INCLUDE_DIRS           		/ścieżka/do/hdf5-vfd/include
HDF5_LIBRARY                		/ścieżka/do/hdf5-vfd/lib/libhdf5
ICET_BUILD_TESTING          		OFF
QCG_VIS_ENABLE              		ON
PARAVIEW_USE_MPI            		ON
PARAVIEW_BUILD_QT_GUI       		ON
NETCDF_ENABLE_NETCDF4       		OFF
VTK_USE_SYSTEM_HDF5         		ON
XDMF_USE_H5FD_DSM           		ON
PARAVIEW_BUILD_PLUGIN_PointSprite   OFF
Kompilacja oraz instalacja
make && make install

 

Wtyczka Icarus

W celu umożliwienia zdalnej wizualizacji i sterowania obliczeniami należy zainstalować wtyczkę do ParaView - Icarus 0.9.9 QCG-Vis

Przygotowanie do instalacji
tar -xzf icarus-0.9.9-qcg-vis.tgz
cd icarus-0.9.9-client
mkdir build
cd build
ccmake ..
Parametry kompilacji
ParaView_DIR      		/ścieżka/do/katalogu/build/paraview
CMAKE_BUILD_TYPE 		Release
CMAKE_INSTALL_PREFIX	ścieżka/instalacji
Kompilacja oraz instalacja
make && make install

QCGVisClient

QCGVisClient to działająca w tle aplikacja, która na bieżąco sprawdza status zleconego zadania wizualizacji in-situ - usługi QCG-Vis. W przypadku rozpoczęcia zadania, aplikacja uruchamia narzędzie ParaView, automatycznie wypełniając niezbędne dane do połączenia z serwerem wizualizacji. 

Aplikację QCGVisClient  należy pobrać z repozytorium GIT i skompilować:

Pobranie oraz instalacja QCGVisClient
git clone https://git.man.poznan.pl/stash/scm/qcgvis/qcg-visclient.git
ant jar
cd dist
#uruchomienie przez wywołanie QCG-VisClient lub QCG-VisClient.bat (środowisko Windows)

 

 Po pomyślnej kompilacji należy upewnić się, czy w pliku konfiguracyjnym config.properties (katalog dist) podana właściwą ścieżkę do zainstalowanego ParaView.

Przykładowy ustawienia w config.properties
coordinator_url=http://qcg-broker.man.poznan.pl:21000
paraview_path=/opt/ParaView-3.0.1-qcg-vis/bin/paraview
polling_frequency=5000

 

Przygotowanie aplikacji obliczeniowej

W celu skorzystania z usługi QCG-Vis aplikacja obliczeniowa musi zostać odpowiednio zmodyfikowana. Instrukcje pozwalające na in-situ, a także na sterowanie obliczeniami z poziomu aplikacji ParaView, są możliwe za pomocą wywołań biblioteki hdf5-vfd oraz h5fddsm. Celem kompilacji kodu z tymi bibliotekami należy załadować odpowiednie pakiety:

ładowanie modułów
module load plgrid/libs/hdf5/1.8.9-vfd
module load plgrid/libs/h5fddsm/0.9.9

 

Pliki nagłówkowe oraz biblioteki znajdują się odpowiednio w katalogach $hdf5_vfd_root/include $h5fddsm_root/include oraz $hdf5_vfd_root/lib $h5fddsm_root/lib.

Do współpracy z usługą QCG-Vis wystarczy kilka poleceń API: H5Pcreate, H5Pset_fapl_dsm, H5Fcreate, H5Pclose, H5Fclose. Wymiana danych z usługą QCG-Vis a aplikacją obliczeniową następuje automatycznie w momencie zapisywania danych HDF5. Poniżej zaprezentowano przykładową aplikację, która współpracuje z usługą QCG-Vis (C/C++). 

 

Przykład C/C++
// niezbedne pliki naglowkowe
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <mpi.h>
#include <hdf5.h>
#include <H5FDdsm.h>
#include <unistd.h>


//rozmiar siatki
#define NX 30
#define NY 20
 
void
dummy_sim_step(int ran)
{
    hid_t     file_id;
    hid_t     fapl_id;
    //utworzenie kontekstu QCG-Vis in-situ
    fapl_id = H5Pcreate(H5P_FILE_ACCESS);
    H5Pset_fapl_dsm(fapl_id, MPI_COMM_WORLD, NULL, 0);
    file_id = H5Fcreate("DSM", H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id);
    H5Pclose(fapl_id);
    // przygotowanie losowych danych
    float *x = (float *) malloc((NX+1)*(NY+1) * sizeof(float));
    float *y = (float *) malloc((NX+1)*(NY+1) * sizeof(float));
    int ndx = 0;
    int i,j,did;
    for (j = 0; j < NY+1; j++)
    {
        float yt = (float) j / (float)NY;
        float angle = yt * M_PI;
        for (i = 0; i < NX+1; i++)
        {
            float xt = (float)i / (float)NX;
            float R = (1.-xt)*2. + xt*5.;
            x[ndx] = R * cos(angle);
            y[ndx] = R * sin(angle);
            ndx++;
        }
    }

 
    float *pressure = (float *) malloc((NX+1)*(NY+1) * sizeof(float));
    for (j = 0; j < NY+1; j++)
    {
        for (i = 0; i < NX+1; i++)
        {
            int ndx = j * (NX+1) + i;
            pressure[ndx] = (float) j + ran;
        }
    }
 
 float *velocityx = (float *) malloc((NX+1)*(NY+1) * sizeof(float));
    for (j = 0; j < NY+1; j++)
    {
        for (i = 0; i < NX+1; i++)
        {
            int ndx = j * (NX+1) + i;
            velocityx[ndx] = (float) i + ran;
        }
    }
    // zapis danych
    // odbywa sie w sposob zdefiniowany przez HDF Group
    // to czy dane sa zapisywane do pliku czy wysylane do QCG-Vis
    // decyduje jedynie uzyty sterownik (H5Pset_fapl_dsm)
    hid_t     dataset_id, dataspace_id;
    hsize_t   dims[3];
    herr_t    status;
    const char *coordNames[] = {"/X", "/Y"};
    for(did = 0; did < 2; ++did)
    {
        dims[0] = (NY + 1);
        dims[1] = (NX + 1);
        dataspace_id = H5Screate_simple(2, dims, NULL);
        dataset_id = H5Dcreate(file_id, coordNames[did], H5T_NATIVE_FLOAT, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
        status = H5Dwrite(dataset_id, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, did == 0 ? x : y);
        status = H5Dclose(dataset_id);
        status = H5Sclose(dataspace_id);
    }


    dims[0] = NY+1;
    dims[1] = NX+1;
    dataspace_id = H5Screate_simple(2, dims, NULL);
    dataset_id = H5Dcreate(file_id, "/Pressure", H5T_NATIVE_FLOAT, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    status = H5Dwrite(dataset_id, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL,  H5P_DEFAULT, pressure);
    status = H5Dclose(dataset_id);
    status = H5Sclose(dataspace_id);
    dims[0] = NY + 1;
    dims[1] = NX + 1;
    dataspace_id = H5Screate_simple(2, dims, NULL);


 dataset_id = H5Dcreate(file_id, "/VelocityX", H5T_NATIVE_FLOAT, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    status = H5Dwrite(dataset_id, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, velocityx);
    status = H5Dclose(dataset_id);
    status = H5Sclose(dataspace_id);
    free(x);
    free(y);
    free(pressure);
    free(velocityx);

    status = H5Fclose(file_id);
    sleep(20);
}


 
int
main(int argc, char *argv[])
{
   int no = -1;
   int i = 0;
   int rank, size;
   MPI_Init(&argc, &argv);
   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
   MPI_Comm_size(MPI_COMM_WORLD, &size);
 if (rank==0){
   if (argc!=2){
     printf("Wywolanie programu: %s liczba_iteracji\n", argv[0]);
     return -1;
   }
   if ((no=atoi(argv[1]))<1){
     printf("Blad: liczba iteracji musi wynosic przynajmniej 1\n");
     return -2;
   }
   if (size > 1){
     printf("Blad: to jest przyklad dla jednego procesu MPI\n");
     return -3;
   }
 }
  for (i=0; i<no; i++){
    dummy_sim_step(i);
  }
 MPI_Finalize();
 return 0;
}

 

Przykład można również pobrać do samodzielnej kompilacji:

przykładowa kompilacja
module load plgrid/libs/hdf5/1.8.9-vfd
module load plgrid/libs/h5fddsm/0.9.9
mpicxx -o qcg-vis-example-sim qcg-vis-example.c -lH5FDdsm -lH5FDdsmTools -lhdf5 -lhdf5_hl

 

Opis danych

Do prawidłowej wymiany danych pomiędzy aplikacją obliczeniową a usługą QCG-Vis niezbędne jest poinstruowanie, jakie dane i jakiego typu mają być wizualizowane. Służy do tego format opisu danych HDF5 - XDMF. Plik XDMF można przygotować samemu lub posłużyć się generatorem XDMF, który zostanie zainstalowany wraz z wtyczką Icarus. Szczegółowa instrukcja wraz z przykładami znajduje się na poświęconej generatorowi stronie [ang]

Dla powyższego przykładu aplikacji, opis danych wygląda następująco (pobierz):

Przykładowy opis danych dla ParaView
<!-- przykladowy plik opisujacy dane do wizualizacji, ktore sa wynikiem dzialania aplikacjo -->
<!-- tworca aplikacji decyduje o sposobie przechowywania danych, ich uporzadkowaniu, czy sa to -->
<!-- tablice 2D czy 3D, jakie komponenty sa zapisywane itd itp -->
<!-- warto zwrocic uwage, ze w opisie nie ma informacji o rozmiarach danych czy ich typie -->
<!-- sa one definiowane w aplikacji obliczeniowej -->
<IcarusRoot>
  <Visualization>
<Xdmf>
   <Grid Name="DSM" GridType="Uniform">
     <!-- zdefiniowanie topologi, w tym przypadku X i Y zapisane w osobnych tablicach -->
     <Topology TopologyType="2DSMesh"/>
     <Geometry GeometryType="X_Y">
       <DataItem Name="X">/X</DataItem>
       <DataItem Name="Y">/Y</DataItem>
     </Geometry>
     <!-- cisnienie jako tablica skalarow -->
     <Attribute Name="Pressure" AttributeType="Scalar">
       <DataItem>/Pressure</DataItem>
     </Attribute>
     <!-- predkosc jako tablica skalarow -->
     <Attribute Name="VelocityX" AttributeType="Scalar">
       <DataItem>/VelocityX</DataItem>
     </Attribute>
   </Grid>
</Xdmf>
</Visualization>
</IcarusRoot>

 

 

Korzystania z usługi QCG-Vis

  • Uruchomienie aplikacji QCGVisClient

  • Zlecenia zadania wizualizacyjnego za pomocą narzędzi dostępowych QCG. Przykładowy skrypt z opisem zadania i zlecenie via QCG-SimpleClient:

    qcgvis.sh
    #!/bin/bash
    #QCG host=moss
    #QCG procs=1
    #QCG native=--gres=gpu:1
    module load plgrid/apps/qcgvis/1.0
    export DISPLAY=:0.$CUDA_VISIBLE_DEVICES
    X &
    mpirun -np 1 pvserver --enable-dsm


    Należy ponadto skopiować nr zadania (jobID) celem wprowadzenia do QCGVisClient.

  • Wpisanie numeru zadania wizualizacyjnego w aplikacji QCGVisClient


  • Wczytanie skompilowanej lokalnie wtyczki Icarus (libICARUS) w ParaView w menu Tools->Manage Plugins
     

  • Zlecenie zadania obliczeniowego z wizualizacją in-situ, za pomocą narzędzi dostępowych QCG; skopiowanie identyfikatora zadania
    Przy zlecaniu zadania należy pamiętać o wykorzystaniu skryptu monitorującego, który jest niezbędny do prawidłowego działania usługi in-situ.
    Przykładowe skrypt zlecający zadanie obliczeniowe dla podanego przykładu:

    sim.sh
    #!/bin/bash
    #QCG monitor=monitor-dsm.sh
    #QCG stage-in-file=monitor-dsm.sh
    #QCG host=inula
    
    module load plgrid/libs/h5fddsm/0.9.9
    ./qcg-vis-example-sim 10000

    I zlecenie zadania za pomocą narzędzia QCG-SimpleClient:
    Identyfikator zadania (jobID) będzie trzeba podać w ParaView

  • Wczytanie pliku z opisem danych do wizualizacji w panelu QCG-Vis DSM w ParaView


  • Wprowadzenie identyfikatora zadania obliczeniowego z wizualizacją in-situ


  • Uruchomienie wizualizacji in-situ

Zaawansowane użycie

Usługa QCG-Vis pozwala także na sterowanie obliczeniami z poziomu aplikacji ParaView. Użytkownik może zatrzymywać i wznawiać działanie obliczeń, a także odczytywać wartości wybranych zmiennych czy nawet je modyfikować. Do poprawnego działania niezbędna jest modyfikacja aplikacji obliczeniowej, a także wprowadzenie informacji do opisu danych (sekcja <Interaction>).

Poniżej przedstawiono przykładowy wygląd panelu sterującego w aplikacji ParaView. Pozwala on na zrestartowania obliczeń, odczytanie i zmianę wartości amplitudy (3 komponenty o wartości zmiennoprzecinkowej) oraz siły (za pomocą suwaka). 

 

Sterowanie

Poprzez sterowanie należy rozumieć zatrzymanie i wznowienie obliczeń. Aby umożliwić taką funkcjonalność należy w odpowiednim miejscu w kodzie aplikacji obliczeniowej umieścić polecenie H5FD_dsm_steering_init(MPI_Comm komunikator_mpi, void * bufor), a w każdym miejscu w którym wymagane jest sprawdzenie czy użytkownik wznowił lub zatrzymał obliczenia H5FD_dsm_steering_update(). Wymuszenie pauzy bezpośrednio w kodzie: H5FD_dsm_steering_wait().

Komendy

Przycisk
 <CommandProperty
    name="Restart"
    label="Zrestartuj obliczenia"
    command="ExecuteSteeringCommand">
  </CommandProperty>

 

Wartości zmiennych

Liczba całkowita, 1 komponent
<IntVectorProperty
    name="Sila"
    command="SetSteeringValueInt"
    label="Siła"
    number_of_elements="1"
    default_values="2">
  </IntVectorProperty>
Liczba całkowita (kod aplikacji)
int set=0;
int sila=0;
H5FD_dsm_steering_is_set("Sila", &set);
if (set>0){
	H5FD_dsm_steering_scalar_get("Sila", H5T_NATIVE_INT, &sila);
}
Wartości logiczne (checkbox)
<IntVectorProperty
    name="WaitForGui"
    command="SetSteeringValueInt"
    label="Czekaj na GUI"
    number_of_elements="1"
    default_values="1">
    <BooleanDomain name="bool"/>
  </IntVectorProperty>
Wartość logiczna (kod aplikacji)
int set=0;
int WaitForGui=0;
H5FD_dsm_steering_is_set("WaitForGui", &set);
if (set>0){
	H5FD_dsm_steering_scalar_get("Sila", H5T_NATIVE_INT, &WaitForGui);
}
Liczby rzeczywiste, 3 komponenty
<DoubleVectorProperty
    name="amplitude"
    command="SetSteeringValueDouble"
    label="Amplituda"
    number_of_elements="3"
    default_values="1.0 20.0 30.3">
  </DoubleVectorProperty>
Liczba rzeczywista, 3 komponenty (kod aplikacji obliczeniowej)
int set=0;
double amplitude[3]={0.0, 0.0, 0.0};
H5FD_dsm_steering_is_set("amplitude", &set);
if (set>0){
	H5FD_dsm_steering_vector_get("amplitude", H5T_NATIVE_DOUBLE, 3, &amplitude);
}
Liczba rzeczywista (suwak)
<DoubleVectorProperty
    name="Force"
    command="SetSteeringValueDouble"
    label="Sila"
    number_of_elements="1"
    default_values="2.5">
    <DoubleRangeDomain name="range" min="0.0" max="10.0"/>
  </DoubleVectorProperty>

Liczba rzeczywista, 1 komponenty (kod aplikacji obliczeniowej)
int set=0;
double force=0.0;
H5FD_dsm_steering_is_set("Force", &set);
if (set>0){
	H5FD_dsm_steering_vector_get("Force", H5T_NATIVE_DOUBLE, 1, &force);
}

Przykład użycia

Aplikacja obliczeniowa

Podany wcześniej przykład został rozszerzony o możliwość wzmocnienia prędkości przez użytkownika w trakcie trwania symulacji (zmienna gain). Rozszerzony przykład aplikacji znajduje się poniżej:

Przykład symulacji obliczeniowej ze sterowaniem
// niezbedne pliki naglowkowe
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <mpi.h>
#include <hdf5.h>
#include <H5FDdsm.h>
#include <H5FDdsmSteering.h>
#include <H5FDdsmObject.h>
#include <unistd.h>

//rozmiar siatki
#define NX 30
#define NY 20

//globalne zmienne
//sterowania
int steering_init = 0;
//wartosci wzmocnienia
int gain = 1;

void
dummy_sim_step(int ran)
{
    hid_t     file_id;
    hid_t     fapl_id;


// inicjalizacja sterowania
if (steering_init == 0)
  if (H5FD_dsm_steering_init(MPI_COMM_WORLD) >= 0)
    steering_init=1;
// odczyt interesujacych zmiennych

if (steering_init == 1){
  if (H5FD_dsm_steering_begin_query() >= 0){
    if (H5FD_dsm_steering_is_enabled("gain")>=0){
      H5FD_dsm_steering_vector_get("gain", H5T_NATIVE_INT, 1, &gain);
      H5FD_dsm_steering_end_query();
    }
  }
}

    printf("Wartosc wzmocnienia: %d\n", gain);

    //utworzenie kontekstu QCG-Vis in-situ
    fapl_id = H5Pcreate(H5P_FILE_ACCESS);
    H5Pset_fapl_dsm(fapl_id, MPI_COMM_WORLD, NULL, 0);
    file_id = H5Fcreate("DSM", H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id);
    H5Pclose(fapl_id);
    // przygotowanie losowych danych
    float *x = (float *) malloc((NX+1)*(NY+1) * sizeof(float));
    float *y = (float *) malloc((NX+1)*(NY+1) * sizeof(float));
    int ndx = 0;
    int i,j,did;

    for (j = 0; j < NY+1; j++)
    {
        float yt = (float) j / (float)NY;
        float angle = yt * M_PI;
        for (i = 0; i < NX+1; i++)
        {
            float xt = (float)i / (float)NX;
            float R = (1.-xt)*2. + xt*5.;
            x[ndx] = R * cos(angle);
            y[ndx] = R * sin(angle);
            ndx++;
        }
    }


 float *pressure = (float *) malloc((NX+1)*(NY+1) * sizeof(float));

    for (j = 0; j < NY+1; j++)
    {
        for (i = 0; i < NX+1; i++)
        {
            int ndx = j * (NX+1) + i;
            pressure[ndx] = (float) j + ran;
        }
    }

    float *velocityx = (float *) malloc((NX+1)*(NY+1) * sizeof(float));

    for (j = 0; j < NY+1; j++)
    {
        for (i = 0; i < NX+1; i++)
        {
            int ndx = j * (NX+1) + i;
            velocityx[ndx] = (float) j + ran;
            velocityx[ndx] *= gain;
        }
    }

    // zapis danych
    // odbywa sie w sposob zdefiniowany przez HDF Group
    // to czy dane sa zapisywane do pliku czy wysylane do QCG-Vis
    // decyduje jedynie uzyty sterownik (H5Pset_fapl_dsm)
    hid_t     dataset_id, dataspace_id;
    hsize_t   dims[3];
    herr_t    status;
    const char *coordNames[] = {"/X", "/Y"};

 for(did = 0; did < 2; ++did)
    {
        dims[0] = (NY + 1);
        dims[1] = (NX + 1);
        dataspace_id = H5Screate_simple(2, dims, NULL);
        dataset_id = H5Dcreate(file_id, coordNames[did], H5T_NATIVE_FLOAT, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
        status = H5Dwrite(dataset_id, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, did == 0 ? x : y);
        status = H5Dclose(dataset_id);
        status = H5Sclose(dataspace_id);
    }
    dims[0] = NY+1;
    dims[1] = NX+1;
    dataspace_id = H5Screate_simple(2, dims, NULL);
    dataset_id = H5Dcreate(file_id, "/Pressure", H5T_NATIVE_FLOAT, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);

    status = H5Dwrite(dataset_id, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL,  H5P_DEFAULT, pressure);
    status = H5Dclose(dataset_id);
    status = H5Sclose(dataspace_id);

    dims[0] = NY + 1;
    dims[1] = NX + 1;
    dataspace_id = H5Screate_simple(2, dims, NULL);
    dataset_id = H5Dcreate(file_id, "/VelocityX", H5T_NATIVE_FLOAT, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);

    status = H5Dwrite(dataset_id, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, velocityx);
    status = H5Dclose(dataset_id);
    status = H5Sclose(dataspace_id);
    free(x);
    free(y);
    free(pressure);
    free(velocityx);

    status = H5Fclose(file_id);
    sleep(10);

  if (steering_init == 1){
    //uaktualnienie wartosci zmiennych wprowadzonych w kliencie graficznym
    H5FD_dsm_steering_update();
  }
}

int
main(int argc, char *argv[])
{
   int no = -1;
   int i = 0;
   int rank, size;

  MPI_Init(&argc, &argv);
   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
   MPI_Comm_size(MPI_COMM_WORLD, &size);

 if (rank==0){
   if (argc!=2){
     printf("Wywolanie programu: %s liczba_iteracji\n", argv[0]);
     return -1;
   }

   if ((no=atoi(argv[1]))<1){
     printf("Blad: liczba iteracji musi wynosic przynajmniej 1\n");
     return -2;
   }

   if (size > 1){
     printf("Blad: to jest przyklad dla jednego procesu MPI\n");
     return -3;
   }
 }

  for (i=0; i<no; i++){
    dummy_sim_step(i);
  }
 MPI_Finalize();

 return 0;

}

 

Powyższy przykład można pobrać i skompilować za pomocą wywołania:

kompilacja przykładu
module load plgrid/libs/hdf5/1.8.9-vfd
module load plgrid/libs/h5fddsm/0.9.9
mpicxx -o qcg-vis-example-sim-with-steering qcg-vis-example-sim-with-steering.c -lH5FDdsm -lH5FDdsmTools -lhdf5 -lhdf5_hl

Opis danych

Do prawidłowej wymiany danych pomiędzy aplikacją obliczeniową a usługą QCG-Vis niezbędne jest poinstruowanie, jakie dane i jakiego typu mają być wizualizowane oraz modyfikowane. Dla powyższego przykładu z możliwością zmiany wybranego parametru, należy rozszerzyć opis o informacje dotyczące zmiennych, które chcemy modyfikować.  W tym przypadku jest to zmienna gain (ang. wzmocnienie). Opis danych należy rozszerzyć w stosunku do poprzedniego przykładu o poniższe wpisy (lub pobrać cały gotowy opis: informacje co wizualizować + sterowanie/modyfikacja parametru).

Rozszerzenie opisu danych o informacje sterujące
<Interaction>
  <!-- definicja parametru gain typu całkowitego, domyślna wartość 1 -->
  <IntVectorProperty 
    name="gain" 
    command="SetSteeringValueInt" 
    label="Wzmocnienie"
    number_of_elements="1"
    default_values="1">
  <!-- definicja dopuszczalnego zakresu - suwak -->
  <IntRangeDomain name="range" min="1" max="10"/>
  </IntVectorProperty>
</Interaction>

Uruchomienie

Po uruchomieniu wizualizacji i obliczeń należy:

  • przejść do zakładki Sterowanie
  • wybrać pole prędkości do wizualizacji


  • zmieniając wartość wzmocnienia należy każdorazowo ją zatwierdzić klikając przycisk Apply

 

Wpływ zmiany wartości wzmocnienia jest widoczny poprzez wizualizację pola prędkości VelocityX, im większa wartość wzmocnienia tym większe są wartości prędkości. Zmiany są również widoczne po stronie aplikacji obliczeniowej, która w każdym kroku czasowym wyświetla bieżącą wartość wzmocnienia.

 

Gdzie szukać dalszych informacji?

Problemy i pytania związane z działaniem usługi QCG-Vis należy kierować poprzez Helpdesk PLGrid (kolejka "QosCosGrid").

 

  • No labels