Processamento de texto - Criando um arquivo slurm topology.conf na saída ibnetdiscover

1

Primeiras coisas primeiro: nenhum conhecimento de slurm ou Infiniband é necessário - este é um problema puramente de processamento de texto.
Em segundo lugar - eu estou ciente de ib2slurm - o código está de alguma forma quebrado e possivelmente desatualizado - ele descarta o núcleo toda vez que ele roda independentemente de a existência ou o formato de um arquivo de mapa.

Eu posso reduzir a saída do ibnetdiscover para 37 blocos de linha de cada forma:

Switch  36 "S-0002c90200423e70"     # "MF0;ibsw20:SX6036/U1" enhanced port 0 lid 3 lmc 0
[1] "H-0002c903000c26f2"[1](2c903000c26f3)      # "compute061 HCA-1" lid 49 4xQDR
[2] "H-0002c903000bf36e"[1](2c903000bf36f)      # "compute060 HCA-1" lid 1 4xQDR
[3] "H-0002c903000bf35a"[1](2c903000bf35b)      # "compute063 HCA-1" lid 28 4xQDR
[4] "H-0002c903000c2646"[1](2c903000c2647)      # "compute062 HCA-1" lid 25 4xQDR
[5] "H-0002c903000bf35e"[1](2c903000bf35f)      # "compute064 HCA-1" lid 31 4xQDR
[6] "H-0002c903000c26de"[1](2c903000c26df)      # "compute065 HCA-1" lid 47 4xQDR
[7] "S-0002c90200423e80"[31]        # "Infiniscale-IV Mellanox Technologies" lid 6 4xQDR
[8] "S-0002c90200423e80"[32]        # "Infiniscale-IV Mellanox Technologies" lid 6 4xQDR
[9] "S-0002c90200423e80"[33]        # "Infiniscale-IV Mellanox Technologies" lid 6 4xQDR
[10]    "S-0002c90200423e80"[34]        # "Infiniscale-IV Mellanox Technologies" lid 6 4xQDR
[11]    "S-0002c90200423e80"[35]        # "Infiniscale-IV Mellanox Technologies" lid 6 4xQDR
[12]    "S-0002c90200423e80"[36]        # "Infiniscale-IV Mellanox Technologies" lid 6 4xQDR
[13]    "S-0002c90200423eb8"[35]        # "Infiniscale-IV Mellanox Technologies" lid 11 4xQDR
[14]    "S-0002c90200423eb8"[36]        # "Infiniscale-IV Mellanox Technologies" lid 11 4xQDR
[15]    "S-0002c90200423eb8"[33]        # "Infiniscale-IV Mellanox Technologies" lid 11 4xQDR
[16]    "S-0002c90200423eb8"[34]        # "Infiniscale-IV Mellanox Technologies" lid 11 4xQDR
[17]    "S-0002c90200423eb8"[31]        # "Infiniscale-IV Mellanox Technologies" lid 11 4xQDR
[18]    "S-0002c90200423eb8"[32]        # "Infiniscale-IV Mellanox Technologies" lid 11 4xQDR
[19]    "S-0002c90200423ee0"[31]        # "Infiniscale-IV Mellanox Technologies" lid 15 4xQDR
[20]    "S-0002c90200423ee0"[32]        # "Infiniscale-IV Mellanox Technologies" lid 15 4xQDR
[21]    "S-0002c90200423ee0"[33]        # "Infiniscale-IV Mellanox Technologies" lid 15 4xQDR
[22]    "S-0002c90200423ee0"[34]        # "Infiniscale-IV Mellanox Technologies" lid 15 4xQDR
[23]    "S-0002c90200423ee0"[35]        # "Infiniscale-IV Mellanox Technologies" lid 15 4xQDR
[24]    "S-0002c90200423ee0"[36]        # "Infiniscale-IV Mellanox Technologies" lid 15 4xQDR
[25]    "H-0002c903000c26fa"[1](2c903000c26fb)      # "compute046 HCA-1" lid 112 4xQDR
[26]    "H-0002c903000c26e2"[1](2c903000c26e3)      # "compute047 HCA-1" lid 63 4xQDR
[27]    "H-0002c903000c263a"[1](2c903000c263b)      # "compute048 HCA-1" lid 59 4xQDR
[28]    "H-0002c903000c27c2"[1](2c903000c27c3)      # "compute049 HCA-1" lid 117 4xQDR
[29]    "H-0002c903000c27a6"[1](2c903000c27a7)      # "compute051 HCA-1" lid 34 4xQDR
[30]    "H-0002c903000c2732"[1](2c903000c2733)      # "compute050 HCA-1" lid 22 4xQDR
[31]    "H-0002c903000c265e"[1](2c903000c265f)      # "compute052 HCA-1" lid 29 4xQDR
[32]    "H-0002c903000c266a"[1](2c903000c266b)      # "compute055 HCA-1" lid 32 4xQDR
[33]    "H-0002c903000c264e"[1](2c903000c264f)      # "compute054 HCA-1" lid 26 4xQDR
[34]    "H-0002c903000c26ee"[1](2c903000c26ef)      # "compute056 HCA-1" lid 48 4xQDR
[35]    "H-0002c903000bf246"[1](2c903000bf247)      # "compute057 HCA-1" lid 33 4xQDR
[36]    "H-0002c903000c27ca"[1](2c903000c27cb)      # "compute053 HCA-1" lid 44 4xQDR

e pode extrair o nome do nó, por ex. compute061 usando awk ou sed.

Eu gostaria de obter uma única linha para cada bloco começando com o nome do switch seguido pelos nomes dos nós, ou seja: ibsw20 compute061 compute060 compute063 compute062 compute064 compute065 compute046 compute047 compute048 compute049 compute051 compute050 compute052 compute055 compute054 compute056 compute057 compute053

Eu pretendo usar o scontrol show hostlist "<nodename> <nodename> ..." do slurm para compactar vários nós em uma única entidade para inserir no arquivo topology.conf do slurm, que deve ter o formato:

SwitchName=ibsw20 Nodes=compute[046-057,060-061]

Alguma idéia?

Devo mencionar depois de todos os mapeamentos de switches, o arquivo ibnetdiscover continua com o inverso - um mapeamento nó a nó para switches, no formato:

vendid=0x2c9
devid=0x673c
sysimgguid=0x2c903000bf371
caguid=0x2c903000bf36e
Ca  1 "H-0002c903000bf36e"      # "compute060 HCA-1"
[1](2c903000bf36f)  "S-0002c90200423e70"[2]     # lid 1 lmc 0 "MF0;ibsw20:SX6036/U1" lid 3 4xQDR

Cada bloco é separado por linhas vazias.

Uma pergunta reduzida que pode me iniciar - como eu analiso várias linhas de texto em uma única linha, extraindo partes diferentes de cada linha (tratando linhas de cabeçalho e corpo de maneira diferente) e descartando linhas que não contêm dados relevantes? / p>

EDITAR: Os blocos podem não estar cheios - se nada estiver conectado a algumas das portas em alguns dos switches, a saída irá ignorar essas linhas e pode resultar em algo como:

Switch  36 "S-0002c90200423e70"     # "MF0;ibsw20:SX6036/U1" enhanced port 0 lid 3 lmc 0
[2] "H-0002c903000bf36e"[1](2c903000bf36f)      # "compute060 HCA-1" lid 1 4xQDR
[3] "H-0002c903000bf35a"[1](2c903000bf35b)      # "compute063 HCA-1" lid 28 4xQDR
[4] "H-0002c903000c2646"[1](2c903000c2647)      # "compute062 HCA-1" lid 25 4xQDR
[15]    "S-0002c90200423eb8"[33]        # "Infiniscale-IV Mellanox Technologies" lid 11 4xQDR
[33]    "H-0002c903000c264e"[1](2c903000c264f)      # "compute074 HCA-1" lid 26 4xQDR
[34]    "H-0002c903000c26ee"[1](2c903000c26ef)      # "compute076 HCA-1" lid 48 4xQDR 

Portanto, não posso simplesmente contar que existem 36 linhas seguindo cada linha de comutação ou que [36] será sempre a última linha de um bloco de comutação.

    
por Dani_l 15.01.2016 / 08:08

2 respostas

2

Q1

Este comando awk extrai uma lista ordenada de nomes de computadores exclusivos do arquivo, assumindo:

O arquivo de origem é muito mais longo, tendo um bloco de linhas para cada switch.
Um script para obter um bloco de comutação inteiro (supondo que a linha de comutação é sempre a primeira linha de um conjunto contínuo de linhas para cada comutador) classificado e removendo nós repetidos é:

awk -v FS='[#"]' '
    BEGIN{c=0}
    $1~/Switch/     {c++; j=0; split($5,arr,"[;:]" ); sw[c,0]=arr[2] }
    $1~/\[[0-9]+\]/ {     j++; split($5,arr," "    ); sw[c,j]=arr[1] }
    END {
            print("final count of switches=" c)
            for (i=1; i<=c; i++) {
                print( "switch=" i, sw[i,0] )     # show switch number.
                split("", out , ":" )             # delete array "out".
                split("", indices , ":" )         # delete array "indices".
                j=0
                while (sw[i,++j]) {               # for all array elements.
                    if (out[sw[i,j]]++ < 1) {     # Is it a new value?
                        indices[sw[i,j]]=j        # add to array "indices".
                    }
                }
                n=asorti(indices)                 # sort the keys of indices
                printf( "%s ", sw[i,0] )
                for (k=1; k<=n; k++) {            # all values for a switch.
                    printf( "%s ", indices[k] )
                }
                printf( "%s\n", "" )
            }
    }
    ' infile

Resultados:

final count of switches=3
switch=1 ibsw20
ibsw20 Infiniscale-IV compute060 compute061 compute062 compute063
compute064 compute065 compute066 compute067 compute068 compute069
compute070 compute071 compute072 compute073 compute074 compute075
compute076 compute077 
switch=2 ibsw21
ibsw21 Infiniscale-IV compute060 compute061 compute062 compute063
compute064 compute065 compute066 compute067 compute068 compute069
compute070 compute071 compute072 compute073 compute074 compute075
compute076 compute077 
switch=3 ibsw22
ibsw22 Infiniscale-IV compute060 compute062 compute063 compute074 
compute076

Não tenho certeza se o Infiniscale-IV deve ser removido e se você também está solicitando o processamento adicional necessário para obter:

SwitchName=ibsw20 Nodes=compute[060-077] 

Q2

Do "homem awk":

If RS is set to the null string, then records are separated by blank lines.

Esse é o "separador de registro" (RS) definido como null:

awk -v RS='' 'script to process lines' file
    
por 15.01.2016 / 09:04
0

Esta é basicamente a resposta da BinaryZebra, modificada para criar um arquivo de topologia.conf de slurm como definido

ibnetdiscover | awk -v FS='[#"]' '
    BEGIN{c=0}
    $1~/Switch/     {c++; j=0; split($5,arr,"[;:]" ); sw[c,0]=arr[2] }
    $1~/\[[0-9]+\]/ && $2~/^H-/ {     j++; split($5,arr," "    ); sw[c,j]=arr[1] }
    END {
            # print("final count of switches=" c)
            for (i=1; i<=c; i++) {
                printf( "SwitchName=s" i, sw[i,0] )     # show switch number.
                split("", out , ":" )             # delete array "out".
                split("", indices , ":" )         # delete array "indices".
                j=0
                while (sw[i,++j]) {               # for all array elements.
                    if (out[sw[i,j]]++ < 1) {     # Is it a new value?
                        indices[sw[i,j]]=j        # add to array "indices".
                    }
                }
                n=asorti(indices)                 # sort the keys of indices
                # printf( "%s ", sw[i,0] )
                printf ( " Nodes=" )
                for (k=1; k<n; k++) {            # all values for a switch.
                    printf( "%s,", indices[k] )
                }
                printf( "%s\n", indices[n] )
            }
    }
    ' | sed -r '/Nodes=$/d' | awk '{sub(/[0-9]+/, ++i)}1; END{printf( "SwitchName=s%s Switches=s[1-%s]\n", NR+1, NR )}'

Se uma lista de hosts condensada for desejada, basta modificar cada Nó = linha usando scontrol show hostlist . O pipe final modificado se pareceria com:

| awk -F= '{sub(/[[:digit:]]+/, ++i) ; cmd= "scontrol show hostlist " $3 ; cmd | getline line ; printf( "%s=%s=%s\n" , $1, $2, line ) } END{printf( "SwitchName=s%s Switches=s[1-%s]\n", NR+1, NR )}'
    
por 05.02.2016 / 17:05