AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / user-7462275

Stef1611's questions

Martin Hope
Stef1611
Asked: 2025-04-19 19:48:58 +0800 CST

"%" em uma matriz de tipo derivado de Fortran cria uma cópia na memória?

  • 7

Gostaria de saber como "%" funciona em uma matriz de tipo derivado.

Eu escrevi o seguinte programa onde o operador "+" foi sobrecarregado:

module my_mod

  implicit none

  type :: my_type
    real :: r1 , r2
    integer :: i1, i2
  end type my_type
  
  interface operator(+)
    module procedure add_my_type_vec, add_my_type
  end interface
  
contains
  function add_my_type_vec(a,b) result(res)
    type(my_type), dimension(:),intent(in) :: a, b
    type(my_type), dimension(size(a)) :: res

      res%r1 = a%r1 + b%r1
      res%r2 = a%r2 + b%r2
      res%i1 = a%i1 + b%i1
      res%i2 = a%i2 + b%i2
      
  end function add_my_type_vec
  
  function add_my_type(a,b) result(res)
    type(my_type), intent(in) :: a, b
    type(my_type) :: res

      res%r1 = a%r1 + b%r1
      res%r2 = a%r2 + b%r2
      res%i1 = a%i1 + b%i1
      res%i2 = a%i2 + b%i2
      
  end function add_my_type
  
end module my_mod

program my_pgm
    use my_mod
    implicit none
    
    type(my_type),allocatable, dimension(:) :: my_vec1, my_vec2, my_vec3
    
    write(*,*) "Sum on type : ", my_type(1.0, 2.0, 1, 2) + my_type(1.0, 2.0, 1, 2)

    allocate(my_vec1(1000), my_vec2(1000), my_vec3(1000))
    my_vec1 = my_type(1.0, 2.0, 1, 2)
    my_vec2 = my_type(1.0, 2.0, 1, 2)
    my_vec3 = my_vec1 + my_vec2
    
    write(*,*) "Sum on vec of type : ", my_vec3(123)
    

end program my_pgm

Na add_my_type_vecfunção, como %funciona? Por exemplo, na instrução res%r1 = a%r1 + b%r1, há a criação (ou seja, cópia de memória) de dois arrays de reais que contêm apenas a%r1e b%r1, a soma é feita nesses arrays e, em seguida, a atribuição é feita em res%r1? Acho que é mais complicado.

fortran
  • 2 respostas
  • 96 Views
Martin Hope
Stef1611
Asked: 2025-04-09 00:03:15 +0800 CST

Sobrecarga de procedimento com uma variável alocável como parâmetro em fortran

  • 6

Estou aprendendo POO em Fortran. E me pergunto sobre o interesse de sobrecarregar procedimentos com limite de tipo quando o tipo de um argumento não é conhecido em tempo de compilação.

Deixe-me explicar, passo a passo, meu problema (Esses programas são apenas exemplos para aumentar minha habilidade em fortran)

Primeiro programa: sobrecarga de um procedimento de tipo limitado

module my_mod

  implicit none
  
  type :: my_type_t
    character(len=128) :: my_text
  contains
    procedure :: integer_print, real_print
    generic :: my_print => integer_print, real_print
  end type my_type_t
  
  contains
  
  subroutine integer_print(this, my_int)
    class(my_type_t), intent(in) :: this
    integer, intent(in) :: my_int
    write (*,"(a,a,i0)") trim(this%my_text),' integer ', my_int
  end subroutine integer_print
  
  subroutine real_print(this, my_real)
    class(my_type_t), intent(in) :: this
    real, intent(in) :: my_real
    write (*,"(a,a,f0.3)") trim(this%my_text),' real ', my_real
  end subroutine real_print

end module my_mod

program my_pgm

  use my_mod
  implicit none
  
  type(my_type_t) :: my_var
  my_var%my_text = "Hello"
  
  call my_var%my_print(10)
  call my_var%my_print(9.9)

end program my_pgm

Deu o resultado esperado. Ou integer_printou real_printé usado, dependendo do tipo de my_printargumento (inteiro ou real).

Segundo programa (ou passo, eu diria): um tipo abstrato é usado e há dois tipos derivados: my_int_te my_real_t. É muito semelhante ao primeiro exemplo. Mas, dois tipos são usados, um para inteiros e outro para reais.

module my_mod

  implicit none
  
  type, abstract :: my_abstract_t
  end type  my_abstract_t
  
  type, extends(my_abstract_t) :: my_int_t
    integer :: an_integer
  end type my_int_t
  
  type, extends(my_abstract_t) :: my_real_t
    real :: a_real
  end type my_real_t
  
  type :: my_type_t
    character(len=128) :: my_text
  contains
    procedure :: integer_print, real_print
    generic :: my_print => integer_print, real_print
  end type my_type_t
  
  contains
  
  subroutine integer_print(this, my_int)
    class(my_type_t), intent(in) :: this
    type(my_int_t), intent(in) :: my_int
    write (*,"(a,a,i0)") trim(this%my_text),' integer ', my_int%an_integer
  end subroutine integer_print
  
  subroutine real_print(this, my_real)
    class(my_type_t), intent(in) :: this
    type(my_real_t), intent(in) :: my_real
    write (*,"(a,a,f0.3)") trim(this%my_text),' real ', my_real%a_real
  end subroutine real_print

end module my_mod

program my_pgm

  use my_mod
  implicit none
  
  type(my_type_t) :: my_var
  type(my_int_t) :: my_int
  type(my_real_t) :: my_real
  
  my_var%my_text = "Hello"
  
  my_int%an_integer = 10
  my_real%a_real = 9.9
  
  call my_var%my_print(my_int)
  call my_var%my_print(my_real)

end program my_pgm

O tipo de my_intand my_realé conhecido no momento da compilação, portanto a saída está correta. E a mesma chamada my_var%my_print(...)é usada independentemente do tipo da variável ( my_int_tor my_real_t), como no primeiro exemplo.

Mas agora esse é o meu problema.

program my_pgm

  use my_mod
  implicit none
  
  type(my_type_t) :: my_var
  class(my_abstract_t), allocatable :: my_number
  
  allocate(my_int_t::my_number)
  ! or allocate(my_real_t::my_number)
  
  my_var%my_text = "Hello"

  select type (my_number)
  type is (my_int_t)
      my_number%an_integer = 10
  type is (my_real_t)
      my_number%a_real = 9.9
  end select
  
  select type (my_number)
  type is (my_int_t)
      call my_var%my_print(my_number)
  type is (my_real_t)
      call my_var%my_print(my_number)
  end select

end program my_pgm

O tipo de my_numbernão é conhecido em tempo de compilação. Então, preciso usar um trecho de código que achei bastante redundante:

  select type (my_number)
  type is (my_int_t)
      call my_var%my_print(my_number)
  type is (my_real_t)
      call my_var%my_print(my_number)
  end select

Eu teria preferido escrever apenas uma linha: call my_var%my_print(...)como no primeiro e no segundo exemplos. Devo concluir que a sobrecarga de procedimento não tem interesse no terceiro exemplo e é melhor usar integer_printe real_printdiretamente no select typebloco? Ou há algo que eu não entendi?

Edição 1

Seguindo os comentários de Francescalus, se entendi bem, não consegui evitar o select typebloqueio. Então, modifiquei o programa da seguinte maneira.

module my_mod

  implicit none
  
  type, abstract :: my_abstract_t
  end type  my_abstract_t
  
  type, extends(my_abstract_t) :: my_int_t
    integer :: an_integer
  end type my_int_t
  
  type, extends(my_abstract_t) :: my_real_t
    real :: a_real
  end type my_real_t
  
  type :: my_type_t
    character(len=128) :: my_text
  contains
    procedure, private :: real_print, integer_print
    procedure, public :: my_print
  end type my_type_t
  
  contains
  
  subroutine integer_print(this, my_int)
    class(my_type_t), intent(in) :: this
    type(my_int_t), intent(in) :: my_int
    write (*,"(a,a,i0)") trim(this%my_text),' integer ', my_int%an_integer
  end subroutine integer_print
  
  subroutine real_print(this, my_real)
    class(my_type_t), intent(in) :: this
    type(my_real_t), intent(in) :: my_real
    write (*,"(a,a,f0.3)") trim(this%my_text),' real ', my_real%a_real
  end subroutine real_print
  
  subroutine my_print(this,my_number)
    class(my_type_t), intent(in) :: this
    class(my_abstract_t), intent(in) :: my_number
    
    select type (my_number)
    type is (my_int_t)
        call this%integer_print(my_number)
    type is (my_real_t)
        call this%real_print(my_number)
    end select
    
  end subroutine my_print
    

end module my_mod

program my_pgm

  use my_mod
  implicit none
  
  type(my_type_t) :: my_var
  class(my_abstract_t), allocatable :: my_number1, my_number2
  
  my_number1 = my_int_t(an_integer = 10)
  my_number2 = my_real_t(a_real = 9.9)
  
  my_var%my_text = "Hello"

  call my_var%my_print(my_number1)
  call my_var%my_print(my_number2)
  
end program my_pgm

Qualquer comentário será apreciado.

oop
  • 1 respostas
  • 58 Views
Martin Hope
Stef1611
Asked: 2025-02-27 01:24:40 +0800 CST

Como usar a redução openmp em uma matriz de tipos derivados em fortran?

  • 6

Desde o OpenMP 4.5, arrays podem ser reduzidos usando pragmas. Mas, eu enfrentei um problema quando tentei usá-lo em arrays de tipo derivado porque !$OMP DECLARE REDUCTION não foi encontrado para este tipo. Eu entendo o problema. Depois de muitas tentativas, eu finalmente encontrei um programa que parece funcionar. Este é o código:

O módulo ( module.f90):

module my_mod
    implicit none
    
    type :: my_type_t
        integer :: x
        integer :: y
    end type my_type_t
    
    interface operator(+)
    module procedure add_my_type_t_vec
    end interface
    
!$OMP DECLARE REDUCTION (+ : my_type_t : omp_out = omp_out + omp_in) INITIALIZER (omp_priv = omp_orig)
    
contains
    
    function add_my_type_t_vec(a,b) result(res)
        type(my_type_t), dimension(:),intent(in) :: a, b
        type(my_type_t), dimension(size(a)) :: res
        
        res(:)%x = a(:)%x + b(:)%x
        res(:)%y = a(:)%y + b(:)%y
    end function add_my_type_t_vec
    
end module my_mod

E o programa ( pgm.f90) que o utiliza:

program parallel
    use omp_lib
    use my_mod
    implicit none
    
    type(my_type_t), dimension(:), allocatable :: private_var, shared_var
    integer :: i
    
    allocate(private_var(5), shared_var(5))
    shared_var%x=0
    shared_var%y=0
    

!$OMP PARALLEL NUM_THREADS(4) PRIVATE(private_var,i) REDUCTION (+ : shared_var) 

    !$OMP DO
    
    do i=1,1000
        private_var%x = 1
        private_var%y = 2
        shared_var = shared_var + private_var
    end do
    
    !$OMP END DO

!$OMP END PARALLEL
    print *, "Total : ", shared_var

end program parallel

Compilação com:gfortran -fopenmp module.f90 pgm.f90

Para encontrar essa solução, usei a seguinte resposta https://stackoverflow.com/a/61148205/7462275 .

Funciona, mas não tenho certeza de que não terei comportamento indefinido em certas circunstâncias. E não entendo completamente a sintaxe e o mecanismo dos pragmas DECLARE REDUCTION e INITIALIZER. De fato, fiz uma cópia/colagem da resposta mencionada acima e não há explicação nela. Obrigado pelos conselhos e explicações.

arrays
  • 1 respostas
  • 55 Views
Martin Hope
Stef1611
Asked: 2024-11-05 20:55:05 +0800 CST

Como preencher espaços entre subplots com uma cor no Matplotlib?

  • 8

Com o seguinte código:

nb_vars=4

fig, axs = plt.subplots(4,4,figsize=(8,8), gridspec_kw = {'wspace':0.20, 'hspace':0.20}, dpi= 100)
for i_ax in axs:
    for ii_ax in i_ax:
        ii_ax.set_yticklabels([])
for i_ax in axs:
    for ii_ax in i_ax:
        ii_ax.set_xticklabels([])

O espaço entre os subplots é branco. Como é possível colori-los? E com cores diferentes? Veja por exemplo esta figura: insira a descrição da imagem aqui

python
  • 1 respostas
  • 47 Views
Martin Hope
Stef1611
Asked: 2024-03-14 23:30:04 +0800 CST

Como definir um ponteiro para um número inteiro em um literal composto inicializado em uma função?

  • 6

Tentei inicializar uma estrutura por meio de um literal composto em uma função. Depois de resolver uma parte do meu problema (veja Uso de literal composto dentro de uma função para iniciar uma variável em C ), tenho um novo problema com um membro ( ptr_mb) que deve ser um ponteiro para uma variável.

Este é o código:

typedef struct {
  int i_mb;
  int * ptr_mb;
} my_struct_t;

void init_struct(my_struct_t **my_struct, int * const ptr) {
  *my_struct=&(static my_struct_t) {.i_mb=3, .ptr_mb= ptr};
}

int main() {
  int a;
  my_struct_t *my_struct;
  
  // my_struct = &(my_struct_t) {.i_mb=3, .ptr_mb=&a}; It is OK

  // Try to initialize it in a function
  init_struct(&my_struct, &a);
  
}

Em main(), funciona (cf linha comentada no programa)

Um erro de compilação foi emitido. Na função init_struct, ptr não é uma constante (linha *my_struct=&(static my_struct_t) {.i_mb=3, .ptr_mb= ptr};:).

aé uma variável declarada em main(). Assim, seu endereço é constante. Tentei lançar a afetação com (int const *), (int * const), (int const * const), .... Às vezes era bobagem, mas só para tentar e nada funcionou.

É possível fazer tal inicialização em uma função, do jeito que ela funciona main()?

(Rq. staticé usado. Eu sei que é um padrão C23 e esse padrão ainda não foi publicado; para obter detalhes, consulte esta resposta: Uso de literal composto dentro de uma função para iniciar uma variável em C .)

c
  • 2 respostas
  • 66 Views
Martin Hope
Stef1611
Asked: 2024-03-14 21:41:10 +0800 CST

Por que é possível alterar indiretamente o valor de um número inteiro através de um ponteiro para uma constante int?

  • 8

Li muitas perguntas antigas, muitas respostas sobre constpalavras-chave em uma declaração para entender profundamente a sintaxe das declarações.

Eu brinquei conste agora estou um pouco confuso com este exemplo:

int i;
i=1;
int const *ptr_i;
ptr_i=&i;
printf("%d\n",*ptr_i);
i=2;
printf("%d\n",*ptr_i);

Se int const *é um ponteiro para um número inteiro constante , por que ptr_i=&i;é permitido? inão é um número inteiro constante.

Além disso, se o valor de ifor alterado de 1 para 2 (obviamente, é possível porque inão é um número inteiro constante), o segundo printfexibirá 2. Não estou surpreso porque o valor de ifoi alterado e ptr_ié um ponteiro para i.

Também verifiquei se o valor de ptr_i não mudou ( printf("%p ",ptr_i)).

Onde está meu mal-entendido?

c
  • 2 respostas
  • 57 Views
Martin Hope
Stef1611
Asked: 2023-08-19 21:52:20 +0800 CST

Como é possível explicar a grande diferença de velocidade de execução entre dois processadores?

  • 7

Eu escrevi um programa fortran para simular o sistema molecular. Eu o desenvolvi em um computador desktop cujo processador é um Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz. Depois, para iniciar a simulação em larga escala, usei blades de computação cujos processadores são AMD Opteron(tm) Processor 6176 @ 2.3 GHz. Fiquei surpreso porque o tempo de execução é aumentado por um fator de cerca de 3.

Então, decidi aprender a usar perf, asm, ... para otimizar o programa. Depois de muita coisa, finalmente escrevi este pequeno programa e ainda tenho um fator de cerca de 3.

program simple_pgm

    integer :: i, res
    
    res = 0
    do i=1,1000000000
        res = res + i
    enddo
    write(*,*) res

end program simple_pgm

Comando de compilação:gfortran -g -Wall -O2 simple.f90 -o simple

Quando olhei annotate MAIN__no perf report -n, o código assembler é mais ou menos o mesmo.

No processador i7:

     │    res = 0
     │    do i=1,1000000000
     │      mov  $0x1,%eax
     │      xchg %ax,%ax
     │    res = res + i
1095 │10:   add  %eax,%edx
     │    do i=1,1000000000
 1   │      add  $0x1,%eax
     │      cmp  $0x3b9aca01,%eax
     │    ↑ jne  10
     │    enddo

E no Opteron:

     │    res = 0                                                                                                                                  
     │    do i=1,1000000000                                                                                                                         
     │      mov    $0x1,%eax                                                                                                                        
     │    program simple_pgm                                                                                                                        
     │      sub    $0x220,%rsp                                                                                                                      
     │      nop                                                                                                                                     
     │    res = res + i
1972 │10:   add    %eax,%edx                                          
     │    do i=1,1000000000
1524 │      add    $0x1,%eax                                          
     │      cmp    $0x3b9aca01,%eax                                                                                                                 
     │    ↑ jne    10                                                                                                                               
     │    enddo

Gostaria de saber porque na samplecoluna, para a instrução add $0x1,%eax, o valor é muito grande para o processador Opteron ( 1524). E isso poderia explicar o fator de velocidade de execução?

Obrigado pela resposta. Como estou aprendendo ASM, processador e arquitetura de computador, perf, ... (muitas coisas para um iniciante), quaisquer comentários, sugestões serão apreciadas. Estou ciente de que posso estar no caminho errado.

performance
  • 1 respostas
  • 56 Views

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Reformatar números, inserindo separadores em posições fixas

    • 6 respostas
  • Marko Smith

    Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não?

    • 2 respostas
  • Marko Smith

    Problema com extensão desinstalada automaticamente do VScode (tema Material)

    • 2 respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Martin Hope
    Fantastic Mr Fox Somente o tipo copiável não é aceito na implementação std::vector do MSVC 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant Encontre o próximo dia da semana usando o cronógrafo 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor O inicializador de membro do construtor pode incluir a inicialização de outro membro? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul O C++20 mudou para permitir a conversão de `type(&)[N]` de matriz de limites conhecidos para `type(&)[]` de matriz de limites desconhecidos? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann Como/por que {2,3,10} e {x,3,10} com x=2 são ordenados de forma diferente? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve