Your Browser is not longer supported

Please use Google Chrome, Mozilla Firefox or Microsoft Edge to view the page correctly
Loading...

{{viewport.spaceProperty.prod}}

Der Makro SM2GDAT

Der Makro SM2GDAT (SM2-Get-Data) liefert alle Messdaten für das letzte abgeschlossene Messintervall, die auch in den Report-Bildschirmen des SM2 ausgegeben werden. Für jeden Bereich (z.B. TIME-IO, DAB, MEMORY) gibt es einen SM2-Datenpuffer. Der Aufrufer kann mit einem Makro-Aufruf alle SM2-Datenpuffer oder eine frei wählbare Teilmenge aller SM2-Datenpuffer anfordern.

Die angeforderten SM2-Datenpuffer werden vom Makro in einen vom Aufrufer bereitzustellenden Ausgabebereich kopiert; Größe und Adresse des Ausgabebereichs sind beim Aufruf dem Makro als Parameter zu übergeben.

-----------------------------------------------------------------------------
#include "FHDR.H"
#include "SM2GDAT.H"
#include "SM2RC.H"

SM2GDAT( struct SM2GDAT_get_data_mdl SM2_DATA, long length_buffer,
         void *buffer_ptr, unsigned long buffer_flags, char *host_name );
-----------------------------------------------------------------------------

struct SM2GDAT_get_data_mdl SM2_DATA

Diese Struktur vom Typ SM2GDAT_get_data_mdl muss vor dem Aufruf des Makros definiert werden. Nach dem Aufruf kann hier der Returncode und die tatsächlich benötigte Größe des Ausgabebereichs abgefragt werden. Eine Beschreibung der Struktur befindet sich im Abschnitt „Strukturen des Makros SM2GDAT".

long length_buffer

Größe des Ausgabebereiches, in den der Makro die SM2-Datenpuffer kopieren soll; Angabe in Vielfachen von 4 KByte.

void *buffer_ptr

Adresse des Ausgabebereiches, in den der Makro die SM2-Datenpuffer kopieren soll.

unsigned long buffer_flags

Ganzzahlige Variable, deren binärer Wert diejenigen SM2-Datenpuffer angibt, die vom Makro in den Ausgabebereich kopiert werden sollen. Für die Angabe der SM2-Datenpuffer stehen symbolische Konstanten zur Verfügung; sollen mehrere SM2-Datenpuffer in den Ausgabereich kopiert werden, so müssen die entsprechenden symbolischen Konstanten der SM2-Datenpuffer addiert werden (Abschnitt „Beispiel").

Achtung
Dieselbe symbolische Konstante darf nicht mehrmals addiert werden. In einem solchen Fall würden nicht die gewünschten SM2-Datenpuffer geliefert. Insbesondere darf auf SM2GDAT_BUFFER_ALL keine symbolische Konstante addiert werden.
Für Programme, die mit einer früheren Version des Makros erzeugt wurden, gilt Folgendes:

  • Die Programme sind weiterhin ablauffähig und müssen nicht neu übersetzt werden.

  • Bei einer Neuübersetzung muss für die symbolischen Konstanten die logische Operation ODER durch eine Addition ersetzt werden, da sonst Übersetzungsfehler auftreten.

char *host_name

Mithilfe dieses Parameters zur Unterstützung eines Rechnerverbunds kann der Aufrufer die SM2-Daten solcher Rechner abrufen, zu denen mittels des Subsystems MSCF eine Verbindung besteht.

Dazu müssen folgende Bedingungen erfüllt sein:

  • der MSCF-Verbindungstyp ist CCS und der MSCF-Partnertyp ist CCS oder XCS

  • auf dem entfernten Rechner ist das Subsystem SM2 geladen

  • die SM2-Version des entfernten Rechners muss größer oder gleich der SM2GDAT-Version des lokalen Rechners sein.

Der Parameter gibt die Adresse des Feldes an, das den Rechnernamen enthält.Sollen die SM2-Daten eines entfernten Rechners abgerufen werden, so muss in dem Feld der Host-Name des Rechners in der Länge 8 angegeben werden (siehe Handbuch „HIPLEX MSCF“ [8]).
Sollen die SM2-Daten des lokalen Rechners abgerufen werden, so ist das Feld in der Länge 8 mit null (binär) oder dem Leerzeichen zu initialisieren.

Bezeichnung der symbolischen Konstanten

Konstante

Bedeutung

SM2GDAT_BUFFER_ACF

fordert den ACF-Datenpuffer an

SM2GDAT_BUFFER_ALL

fordert alle SM2-Datenpuffer an

SM2GDAT_BUFFER_BASIC

fordert den BASIC-Datenpuffer an

SM2GDAT_BUFFER_BCAM

fordert den BCAM-CONNECTION-Datenpuffer an

SM2GDAT_BUFFER_CATEGORY

fordert den CATEGORY-Datenpuffer an

SM2GDAT_BUFFER_CHANNEL_IO

fordert den CHANNEL-IO-Datenpuffer an

SM2GDAT_BUFFER_CMS

fordert den CMS-Datenpuffer an

SM2GDAT_BUFFER_DAB

fordert den DAB-Datenpuffer an

SM2GDAT_BUFFER_DISK_FILE

fordert den DISK-FILE-Datenpuffer an

SM2GDAT_BUFFER_DLM

fordert den DLM-Datenpuffer an

SM2GDAT_BUFFER_FILE

fordert den FILE-Datenpuffer an

SM2GDAT_BUFFER_HSMS

fordert den HSMS-Datenpuffer an

SM2GDAT_BUFFER_ISAM

fordert den ISAM-Datenpuffer an

SM2GDAT_BUFFER_ISAM_FILE

fordert den ISAM-FILE-Datenpuffer an

SM2GDAT_BUFFER_MEMORY

fordert den MEMORY-Datenpuffer an

SM2GDAT_BUFFER_MSCF

fordert den MSCF-Datenpuffer an

SM2GDAT_BUFFER_NSM

fordert den NSM-Datenpuffer an

SM2GDAT_BUFFER_OPENFT

fordert den OPENFT-Datenpuffer an

SM2GDAT_BUFFER_PERTASK

fordert den PERIODIC-TASK-Datenpuffer an

SM2GDAT_BUFFER_POSIX

fordert den POSIX-Datenpuffer an

SM2GDAT_BUFFER_PUBSET

fordert den PUBSET-Datenpuffer an

SM2GDAT_BUFFER_RTIME

fordert den RESPONSETIME-Datenpuffer an

SM2GDAT_BUFFER_SCHANNEL

fordert den SCHANNEL-Datenpuffer an

SM2GDAT_BUFFER_SDEVICE

fordert den SDEVICE-Datenpuffer an

SM2GDAT_BUFFER_SESAM_SQL

fordert den SESAM-SQL-Datenpuffer an

SM2GDAT_BUFFER_SVC

fordert den SVC-Datenpuffer an

SM2GDAT_BUFFER_SYSTEM

fordert den SYSTEM-Datenpuffer an

SM2GDAT_BUFFER_TCP_IP

fordert den TCP-IP-Datenpuffer an

SM2GDAT_BUFFER_TIME_IO

fordert den TIME-IO-Datenpuffer an

SM2GDAT_BUFFER_TLM

fordert den TLM-Datenpuffer an

SM2GDAT_BUFFER_USERFILE

fordert den USERFILE-Datenpuffer an

SM2GDAT_BUFFER_USERISAM

fordert den USERISAM-Datenpuffer an

SM2GDAT_BUFFER_UDS_SQL

fordert den UDS-SQL-Datenpuffer an

SM2GDAT_BUFFER_UTM

fordert den UTM-Datenpuffer an

SM2GDAT_BUFFER_VM

fordert den VM-Datenpuffer an

SM2GDAT_BUFFER_VM_CPU_POOL

fordert den VM-CPU-POOL-Datenpuffer an

SM2GDAT_BUFFER_VM_GROUP

fordert den VM-GROUP-Datenpuffer an

Returncode

Die Returncodes sind im Standardheader hinterlegt.
Der Standardheader ist eine Struktur vom Typ ESMFHDR und kann über das Strukturelement „hdr“ der Struktur SM2_DATA angesprochen werden. Die Auswertung der Returncodes ist im Abschnitt „Auswertung der Returncodes" beschrieben.

Hinweise

  • SM2GDAT ist als Makro realisiert.

  • Bei Verwendung des Makros muss der Modul ISM2CALL aus der Bibliothek SYSLIB.SM2.<ver> zum Programm dazugebunden werden (für native Code auf x86-Servern: SKULIB.SM2.<ver>).

  • SM2GDAT.H befindet sich in der Bibliothek SYSLIB.SM2.<ver> und kann mit dem folgenden Kommando ausgedruckt werden:

    /PRINT-DOCUMENT 
       FROM-FILE=*LIBRARY-ELEMENT(
          LIBRARY=SYSLIB.SM2.<ver>,
          ELEMENT=SM2GDAT.H,TYPE=S)
    
  • „length_buffer“
    SM2 prüft, ob die beim Parameter „length_buffer“ angegebene Größe des Ausgabebereiches zur Aufnahme der angeforderten SM2-Datenpuffer ausreicht (aber nicht, ob der Aufrufer auch wirklich einen Ausgabebereich mit der in „length_buffer“ angegebenen Größe bereitgestellt hat (etwa mit „malloc“)!).

  • Größe des Ausgabebereiches
    Die Größe einiger Datenpuffer kann sich im laufenden Betrieb dynamisch ändern, z.B. die Größe des PERIODIC-TASK-Datenpuffers (die Anzahl der Tasks ist nicht konstant). Reicht die Größe des Ausgabebereiches nicht aus, so wird ein entsprechender Returncode gesetzt und die tatsächlich benötigte Größe im Strukturelement „length_buffer“ der Struktur SM2_DATA hinterlegt. In diesem Fall ist der Parameter „length_buffer“ mit dem Wert des Strukturelementes „length_buffer“ zu versorgen, ausreichend Speicherplatz bereitzustellen und der Makro-Aufruf mit dem neuen „length_buffer“-Wert zu wiederholen.
    Dies kann der Aufrufer benutzen, um die benötigte Größe für den Ausgabebereich festzustellen, indem er den Makro zunächst mit dem Wert 0 für den Parameter „length_buffer“ aufruft.

  • Bereitstellen des Ausgabebereiches
    Der Ausgabebereich zur Aufnahme der angeforderten SM2-Datenpuffer muss vor dem Aufruf des Makros vom Aufrufer bereitgestellt werden.

    Bevor der Makro mit einem ausreichend großen Wert im Parameter „length_buffer“ aufgerufen wird, muss immer ein Ausgabebereich bereitgestellt werden, der mindestens ebenso groß ist wie der im Parameter „length_buffer“ angegebene Wert. Wenn der Makro aufgerufen wird, um die benötigte Größe des Ausgabebereiches festzustellen, sollte daher immer mit dem Wert 0 für den Parameter „length_buffer“ aufgerufen werden, um zu vermeiden, dass die im Parameter „length_buffer“ angegebene Größe zwar zufällig ausreicht, aber kein Ausgabebereich mit ausreichender Größe zur Verfügung steht.
  • Gültigkeit der SM2-Datenpuffer
    Die Datenpuffer BASIC, TIME-IO, MEMORY, CATEGORY, ACF und SCHANNEL können immer geliefert werden. Für alle anderen Datenpuffer muss das entsprechende Messprogramm aktiv sein; ob ein Messprogramm aktiv ist, kann mit dem Makro SM2GMS überprüft werden. Grundsätzlich sollte für alle angeforderten SM2-Datenpuffer nach dem Aufruf von SM2GDAT vor der Auswertung des Datenpuffers das „valid“-Bit überprüft werden, da es Situationen gibt, in denen der SM2 zwar den Datenpuffer liefert, dieser aber keine gültigen Daten enthält. Das „valid“-Bit kann mit dem Strukturelement „state“ im BUFFER HEADER des Datenpuffers geprüft werden. Der BUFFER HEADER ist im Abschnitt „Strukturen des Makros SM2GDAT" beschrieben, ein Beispiel für die Überprüfung des „valid“-Bits liefert Abschnitt „Beispiel".

  • Messdaten der Datenpuffer
    Das Kapitel „SM2-Bildschirmausgaben" enthält eine detaillierte Beschreibung der in den Datenpuffern gelieferten Messwerte.
    Die Bildschirmreports verwenden die gleiche Schnittstelle. Bei den Messwerten, die in den Datenpuffern geliefert werden, handelt es sich um „Rohdaten“, die erst noch in Einheiten wie Prozent, Zugriffe pro Sekunde usw. umgerechnet werden müssen. So werden z.B. die CPU-Idle-, -TU-, -TPR- und -SIH-Zeiten in der Einheit „0.1 milliseconds“ geliefert; zur Umrechnung in Prozent muss erst durch die Dauer des Messintervalls („elapsed_time“) (Einheit „1/300 seconds“!) dividiert werden.

  • Ein Beispiel zur Verwendung des Makros befindet sich im Abschnitt „Beispiel".

Aufbau des Ausgabebereiches

Im Ausgabebereich erhält der Aufrufer Kopien der angeforderten SM2-Datenpuffer. Diese Kopien sind dem zentralen Datenpuffer entnommen, in den die SM2-Messtask am Ende jedes Online-Intervalls (bzw. Offline-Intervalls, wenn kein Online-Intervall definiert ist) die Messdaten schreibt.

Der Aufbau des Ausgabebereiches ist in folgendem Bild dargestellt.

 

Aufbau des Ausgabebereichs des Makros SM2GDAT

Der Ausgabebereich beginnt mit einem globalen Header, der Zeiger auf die einzelnen Datenpuffer enthält. Den globalen Header beschreibt die Struktur SM2GDAT_global_header_mdl. Die Zeiger auf Datenpuffer, die nicht angefordert wurden, sind mit NULL versorgt.

Alle Datenpuffer haben einen einheitlichen BUFFER HEADER und einen Datenbereich. Den BUFFER HEADER, der Informationen über Gültigkeit und Lage der Messdaten innerhalb des Datenpuffers enthält, beschreibt die Struktur SM2GDAT_buffer_header_mdl. Der Aufbau des Datenbereiches ist abhängig vom Typ des Datenpuffers.

Es gibt vier verschiedene Typen von Datenpuffern (siehe Bild 12: Aufbau des Ausgabebereichs des Makros SM2GDAT), die im Folgenden allgemein erläutert werden; hierbei wird auch erklärt, wie bei den einzelnen Typen mit den Informationen aus dem BUFFER HEADER auf den Datenbereich positioniert wird.

Eine genaue Beschreibung der Strukturen und der einzelnen Datenpuffer befindet sich im Abschnitt „Strukturen des Makros SM2GDAT".

Typ 1 

Der Datenbereich hat eine feste Länge (in der Abbildung als „single“ gekennzeichnet).

Bei diesem Typ liefert das Element „fixed_part_dsp“ des BUFFER HEADERs die Distanz des Datenbereiches vom Anfang des BUFFER HEADERs.

Datenpuffer: ACF, BASIC, DLM, HSMS, MEMORY, MSCF, NSM, POSIX

Typ 2 

Der Datenbereich besteht aus mehreren Wiederholungsgruppen (in der Abbildung als „multiple“ gekennzeichnet), die alle dieselbe Struktur haben; jede Wiederholungsgruppe enthält die Messdaten für ein spezielles Messobjekt.

Bei diesem Typ liefert das Element „first_group_dsp“ des BUFFER HEADERs die Distanz der ersten Wiederholungsgruppe vom Anfang des BUFFER HEADERs. Die weiteren Wiederholungsgruppen liegen hinter der ersten Wiederholungsgruppe. Das Element „length_group“ liefert die Länge einer Wiederholungsgruppe, das Element „number_groups“ die Anzahl der Wiederholungsgruppen im Datenbereich.

Datenpuffer: SCHANNEL, SDEVICE, SVC, UTM

Typ 3 

Der Datenbereich besteht aus einem Bereich fester Länge („single“) und aus mehreren Wiederholungsgruppen („multiple“), die alle dieselbe Struktur haben. Der Bereich fester Länge enthält Daten, die sich nicht auf ein spezielles Messobjekt beziehen; jede Wiederholungsgruppe enthält die Messdaten für ein spezielles Messobjekt.

Bei diesem Typ liefert das Element „fixed_part_dsp“ des BUFFER HEADERs die Distanz des Datenbereiches mit fester Länge vom Anfang des BUFFER HEADERs, das Element „first_group_dsp“ des BUFFER HEADERs die Distanz der ersten Wiederholungsgruppe vom Anfang des BUFFER HEADERs. Die weiteren Wiederholungsgruppen liegen hinter der ersten Wiederholungsgruppe. Das Element „length_group“ liefert die Länge einer Wiederholungsgruppe.

Die Anzahl der Wiederholungsgruppen liefert bei den Datenpuffern BCAM-CONNECTION und CMS das Element „number_groups“ des BUFFER HEADERs und bei den Datenpuffern CATEGORY, CHANNEL-IO, DISK-FILE, FILE, ISAM, PERIODIC-TASK, PUBSET, SESAM-SQL, TCP-IP, TIME-IO, TLM, UDS-SQL, USER- FILE, USERISAM, VM, VM-CPU-POOL und VM-GROUP das Element „used_groups“ im Datenbereich fester Länge. Die Anzahl der tatsächlich gefüllten Wiederholungsgruppen „used_groups“ kann kleiner sein als die Anzahl der vorhandenen „number_groups“.

Datenpuffer: BCAM-CONNECTION, CATEGORY, CHANNEL-IO, CMS, DISK- FILE, FILE, ISAM, PERIODIC-TASK, PUBSET, SESAM-SQL, TCP-IP, TIME-IO, TLM, UDS-SQL, USERFILE, USERISAM, VM, VM-CPU-POOL, VM-GROUP

Typ 4 

Der Datenbereich hat eine „special“-Struktur. Diese Struktur ist im Abschnitt „Strukturen des Makros SM2GDAT" beschrieben.

Bei diesem Typ liefert das Element „fixed_part_dsp“ des BUFFER HEADERs die Distanz des Datenbereiches vom Anfang des BUFFER HEADERs.

Datenpuffer: DAB, RESPONSETIME


Folgende Tabelle enthält eine Übersicht über alle Datenpuffer und die Strukturen, die den Datenbereich des Datenpuffers beschreiben:

Datenpuffer

Typ

Symbolische Konstante zur Auswahl des Datenpuffers in „buffer_flags“

Strukturen

ACF

1

SM2GDAT_BUFFER_ACF

SM2GDAT_acf_single_mdl

BASIC

1

SM2GDAT_BUFFER_BASIC

SM2GDAT_basic_single_mdl

BCAM-CONNECTION

3

SM2GDAT_BUFFER_BCAM

SM2GDAT_bcam_single_mdl
SM2GDAT_bcam_measurement_mdl
SM2GDAT_bcam_multiple_mdl
SM2GDAT_bcam_description_mdl
SM2GDAT_bcam_nea_mdl
SM2GDAT_bcam_port_number_mdl

CATEGORY

3

SM2GDAT_BUFFER_CATEGORY

SM2GDAT_category_single_mdl
SM2GDAT_category_multiple_mdl
SM2GDAT_category_pcs_mdl

CHANNEL-IO

3

SM2GDAT_BUFFER_CHANNEL_IO

SM2GDAT_chio_single_mdl
SM2GDAT_chio_multiple_mdl

CMS

3

SM2GDAT_BUFFER_CMS

SM2GDAT_cms_single_mdl
SM2GDAT_cms_multiple_mdl

DAB

4

SM2GDAT_BUFFER_DAB

SM2GDAT_dab_single_mdl
SM2GDAT_dab_partial_area_mdl
SM2GDAT_dab_cache_transfers_mdl
SM2GDAT_dab_buffer_area_mdl

DISK-FILE

3

SM2GDAT_BUFFER_DISK_FILE

SM2GDAT_disk_file_single_mdl
SM2GDAT_disk_file_multiple_mdl

DLM

1

SM2GDAT_BUFFER_DLM

SM2GDAT_dlm_single_mdl

FILE

3

SM2GDAT_BUFFER_FILE

SM2GDAT_file_single_mdl
SM2GDAT_file_multiple_mdl

HSMS

1

SM2GDAT_BUFFER_HSMS

SM2GDAT_hsms_single_mdl

ISAM

3

SM2GDAT_BUFFER_ISAM

SM2GDAT_isam_single_mdl
SM2GDAT_isam_multiple_mdl

ISAM-FILE

3

SM2GDAT_BUFFER_ISAM_FILE

SM2GDAT_isam_file_single_mdl
SM2GDAT_isam_file_multiple_mdl

MEMORY

1

SM2GDAT_BUFFER_MEMORY

SM2GDAT_memory_single_mdl

MSCF

1

SM2GDAT_BUFFER_MSCF

SM2GDAT_mscf_single_mdl
SM2GDAT_mscf_time_count-mdl

NSM

1

SM2GDAT_BUFFER_NSM

SM2GDAT_nsm_single_mdl
SM2GDAT_tokentab_mdl
SM2GDAT_tokenoptab_mdl
SM2GDAT_lockconvtab_mdl
SM2GDAT_enqlockmodetab_mdl
SM2GDAT_lockoptypetab_mdl
SM2GDAT_lockservicetab_mdl

OPENFT

2

SM2GDAT_BUFFER_OPENFT

SM2GDAT_openft_multiple_mdl

PERIODIC-TASK

3

SM2GDAT_BUFFER_PERTASK

SM2GDAT_pertask_single_mdl
SM2GDAT_pertask_multiple_mdl

POSIX

1

SM2GDAT_BUFFER_POSIX

SM2GDAT_posix_single_mdl

PUBSET

3

SM2GDAT_BUFFER_PUBSET

SM2GDAT_pubset_single_mdl
SM2GDAT_pubset_multiple_mdl

RESPONSE-TIME

4

SM2GDAT_BUFFER_RTIME

SM2GDAT_rtime_single_mdl
SM2GDAT_rtime_connection_mdl
SM2GDAT_rtime_connectionset_mdl
SM2GDAT_rtime_category_list_mdl
SM2GDAT_rtime_bucket_mdl
SM2GDAT_rtime_category_mdl

SCHANNEL

2

SM2GDAT_BUFFER_SCHANNEL

SM2GDAT_schannel_multiple_mdl

SDEVICE

2

SM2GDAT_BUFFER_SDEVICE

SM2GDAT_sdevice_multiple_mdl

SESAM-SQL

3

SM2GDAT_BUFFER_SESAM_SQL

SM2GDAT_sesam_sql_single_mdl
SM2GDAT_sesam_sql_multiple_mdl

SVC

2

SM2GDAT_BUFFER_SVC

SM2GDAT_svc_multiple_mdl

SYSTEM

3

SM2GDAT_BUFFER_SYSTEM

SM2GDAT_system_single_mdl
SM2GDAT_system_multiple_mdl
SM2GDAT_system_queue_data_mdl

TCP-IP

3

SM2GDAT_BUFFER_TCP_IP

SM2GDAT_tcp_ip_single_mdl
SM2GDAT_tcp_ip_multiple_mdl
SM2GDAT_local_addr_mdl
SM2GDAT_remote_addr_mdl

TIME-IO

3

SM2GDAT_BUFFER_TIME_IO

SM2GDAT_time_io_single_mdl
SM2GDAT_time_io_multiple_mdl

TLM

3

SM2GDAT_BUFFER_TLM

SM2GDAT_tlm_single_mdl
SM2GDAT_tlm_multiple_mdl

UDS-SQL

3

SM2GDAT_BUFFER_UDS_SQL

SM2GDAT_uds_sql_single_mdl
SM2GDAT_uds_sql_multiple_mdl

USERFILE

3

SM2GDAT_BUFFER_USERFILE

SM2GDAT_userfile_single_mdl
SM2GDAT_userfile_multiple_mdl

USERISAM

3

SM2GDAT_BUFFER_USERISAM

SM2GDAT_userisam_single_mdl
SM2GDAT_userisam_multiple_mdl

UTM

2

SM2GDAT_BUFFER_UTM

SM2GDAT_utm_multiple_mdl
SM2GDAT_utm_constant_mdl
SM2GDAT_utm_periodic_mdl
SM2GDAT_utm_event_mdl
SM2GDAT_utm_avg_mdl
SM2GDAT_utm_ext_v2_mdl
SM2GDAT_utm_ext_v3_mdl
SM2GDAT_utm_ext_tacclass_mdl

VM

3

SM2GDAT_BUFFER_VM

SM2GDAT_vm_single_mdl
SM2GDAT_vm_multiple_mdl

VM-CPU-POOL

3

SM2GDAT_BUFFER_VM_CPU_POOL

SM2GDAT_vm_cpupool_single_mdl
SM2GDAT_vm_cpupool_multiple_mdl

VM-GROUP

3

SM2GDAT_BUFFER_VM_GROUP

SM2GDAT_vm_group_single_mdl
SM2GDAT_vm_group_multiple_mdl