@@ -427,45 +427,64 @@ def call(
427427 The smooth switch function.
428428 """
429429 del mapping
430+ xp = array_api_compat .array_namespace (coord_ext , atype_ext , nlist )
431+ input_dtype = coord_ext .dtype
430432 # nf x nloc x nnei x 4
431433 rr , diff , ww = self .env_mat .call (
432- coord_ext , atype_ext , nlist , self .davg , self .dstd
434+ coord_ext ,
435+ atype_ext ,
436+ nlist ,
437+ self .davg [...],
438+ self .dstd [...],
433439 )
434440 nf , nloc , nnei , _ = rr .shape
435- sec = np . append ([ 0 ], np . cumsum ( self .sel ))
441+ sec = self .sel_cumsum
436442
437443 ng = self .neuron [- 1 ]
438- gr = np .zeros ([nf * nloc , ng , 4 ], dtype = PRECISION_DICT [self .precision ])
444+ gr = xp .zeros (
445+ [nf * nloc , ng , 4 ],
446+ dtype = input_dtype ,
447+ device = array_api_compat .device (coord_ext ),
448+ )
439449 exclude_mask = self .emask .build_type_exclude_mask (nlist , atype_ext )
440450 # merge nf and nloc axis, so for type_one_side == False,
441451 # we don't require atype is the same in all frames
442- exclude_mask = exclude_mask .reshape (nf * nloc , nnei )
443- rr = rr .reshape (nf * nloc , nnei , 4 )
452+ exclude_mask = xp .reshape (exclude_mask , (nf * nloc , nnei ))
453+ rr = xp .reshape (rr , (nf * nloc , nnei , 4 ))
454+ rr = xp .astype (rr , self .dstd .dtype )
455+
456+ if not self .type_one_side :
457+ # nf x nloc -> (nf * nloc)
458+ atype_loc = xp .reshape (atype_ext [:, :nloc ], (nf * nloc ,))
444459
445460 for embedding_idx in itertools .product (
446461 range (self .ntypes ), repeat = self .embeddings .ndim
447462 ):
448463 if self .type_one_side :
449464 (tt ,) = embedding_idx
450- ti_mask = np .s_ [:]
451465 else :
452466 ti , tt = embedding_idx
453- ti_mask = atype_ext [:, :nloc ].ravel () == ti
454- mm = exclude_mask [ti_mask , sec [tt ] : sec [tt + 1 ]]
455- tr = rr [ti_mask , sec [tt ] : sec [tt + 1 ], :]
456- tr = tr * mm [:, :, None ]
467+ mm = exclude_mask [:, sec [tt ] : sec [tt + 1 ]]
468+ tr = rr [:, sec [tt ] : sec [tt + 1 ], :]
469+ tr = tr * xp .astype (mm [:, :, None ], tr .dtype )
457470 ss = tr [..., 0 :1 ]
458471 gg = self .cal_g (ss , embedding_idx )
459- gr_tmp = np .einsum ("lni,lnj->lij" , gg , tr )
460- gr [ti_mask ] += gr_tmp
461- gr = gr .reshape (nf , nloc , ng , 4 )
472+ gr_tmp = xp .sum (gg [:, :, :, None ] * tr [:, :, None , :], axis = 1 )
473+ if not self .type_one_side :
474+ # (nf * nloc) x 1 x 1
475+ ti_mask = xp .astype (
476+ xp .reshape (atype_loc == ti , (nf * nloc , 1 , 1 )), gr_tmp .dtype
477+ )
478+ gr_tmp = gr_tmp * ti_mask
479+ gr += gr_tmp
480+ gr = xp .reshape (gr , (nf , nloc , ng , 4 ))
462481 # nf x nloc x ng x 4
463482 gr /= self .nnei
464483 gr1 = gr [:, :, : self .axis_neuron , :]
465484 # nf x nloc x ng x ng1
466- grrg = np . einsum ( "flid,fljd->flij" , gr , gr1 )
485+ grrg = xp . sum ( gr [:, :, :, None , :] * gr1 [:, :, None , :, :], axis = 4 )
467486 # nf x nloc x (ng x ng1)
468- grrg = grrg .reshape (nf , nloc , ng * self .axis_neuron )
487+ grrg = xp .reshape (grrg , ( nf , nloc , ng * self .axis_neuron ) )
469488 return grrg , gr [..., 1 :], None , None , ww
470489
471490 def serialize (self ) -> dict :
@@ -553,94 +572,4 @@ def update_sel(
553572 return local_jdata_cpy , min_nbor_dist
554573
555574
556- class DescrptSeAArrayAPI (DescrptSeA ):
557- @cast_precision
558- def call (
559- self ,
560- coord_ext : Array ,
561- atype_ext : Array ,
562- nlist : Array ,
563- mapping : Array | None = None ,
564- ) -> Array :
565- """Compute the descriptor.
566-
567- Parameters
568- ----------
569- coord_ext
570- The extended coordinates of atoms. shape: nf x (nallx3)
571- atype_ext
572- The extended aotm types. shape: nf x nall
573- nlist
574- The neighbor list. shape: nf x nloc x nnei
575- mapping
576- The index mapping from extended to local region. not used by this descriptor.
577-
578- Returns
579- -------
580- descriptor
581- The descriptor. shape: nf x nloc x (ng x axis_neuron)
582- gr
583- The rotationally equivariant and permutationally invariant single particle
584- representation. shape: nf x nloc x ng x 3
585- g2
586- The rotationally invariant pair-partical representation.
587- this descriptor returns None
588- h2
589- The rotationally equivariant pair-partical representation.
590- this descriptor returns None
591- sw
592- The smooth switch function.
593- """
594- if not self .type_one_side :
595- raise NotImplementedError (
596- "type_one_side == False is not supported in DescrptSeAArrayAPI"
597- )
598- del mapping
599- xp = array_api_compat .array_namespace (coord_ext , atype_ext , nlist )
600- input_dtype = coord_ext .dtype
601- # nf x nloc x nnei x 4
602- rr , diff , ww = self .env_mat .call (
603- coord_ext ,
604- atype_ext ,
605- nlist ,
606- self .davg [...],
607- self .dstd [...],
608- )
609- nf , nloc , nnei , _ = rr .shape
610- sec = self .sel_cumsum
611-
612- ng = self .neuron [- 1 ]
613- gr = xp .zeros (
614- [nf * nloc , ng , 4 ],
615- dtype = input_dtype ,
616- device = array_api_compat .device (coord_ext ),
617- )
618- exclude_mask = self .emask .build_type_exclude_mask (nlist , atype_ext )
619- # merge nf and nloc axis, so for type_one_side == False,
620- # we don't require atype is the same in all frames
621- exclude_mask = xp .reshape (exclude_mask , (nf * nloc , nnei ))
622- rr = xp .reshape (rr , (nf * nloc , nnei , 4 ))
623- rr = xp .astype (rr , self .dstd .dtype )
624-
625- for embedding_idx in itertools .product (
626- range (self .ntypes ), repeat = self .embeddings .ndim
627- ):
628- (tt ,) = embedding_idx
629- mm = exclude_mask [:, sec [tt ] : sec [tt + 1 ]]
630- tr = rr [:, sec [tt ] : sec [tt + 1 ], :]
631- tr = tr * xp .astype (mm [:, :, None ], tr .dtype )
632- ss = tr [..., 0 :1 ]
633- gg = self .cal_g (ss , embedding_idx )
634- # gr_tmp = xp.einsum("lni,lnj->lij", gg, tr)
635- gr_tmp = xp .sum (gg [:, :, :, None ] * tr [:, :, None , :], axis = 1 )
636- gr += gr_tmp
637- gr = xp .reshape (gr , (nf , nloc , ng , 4 ))
638- # nf x nloc x ng x 4
639- gr /= self .nnei
640- gr1 = gr [:, :, : self .axis_neuron , :]
641- # nf x nloc x ng x ng1
642- # grrg = xp.einsum("flid,fljd->flij", gr, gr1)
643- grrg = xp .sum (gr [:, :, :, None , :] * gr1 [:, :, None , :, :], axis = 4 )
644- # nf x nloc x (ng x ng1)
645- grrg = xp .reshape (grrg , (nf , nloc , ng * self .axis_neuron ))
646- return grrg , gr [..., 1 :], None , None , ww
575+ DescrptSeAArrayAPI = DescrptSeA
0 commit comments