You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

array_ops.py 208 kB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
6 years ago
5 years ago
6 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
5 years ago
6 years ago
6 years ago
5 years ago
6 years ago
6 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
5 years ago
6 years ago
6 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
5 years ago
6 years ago
6 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252
  1. # coding: utf-8
  2. # Copyright 2020-2021 Huawei Technologies Co., Ltd
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. # ============================================================================
  16. """Operators for array."""
  17. import copy
  18. import functools
  19. import itertools
  20. import numbers
  21. import numpy as np
  22. from mindspore import log as logger
  23. from .._utils import get_concat_offset
  24. from ..operations.math_ops import _infer_shape_reduce
  25. from ..primitive import Primitive, PrimitiveWithInfer, PrimitiveWithCheck, prim_attr_register, _run_op
  26. from .. import signature as sig
  27. from ..._checkparam import Rel
  28. from ..._checkparam import Validator as validator
  29. from ...common import dtype as mstype
  30. from ...common._decorator import deprecated
  31. from ...common.parameter import Parameter
  32. from ...common.tensor import Tensor
  33. class _ScatterOp(PrimitiveWithInfer):
  34. """
  35. Defines Scatter operators
  36. """
  37. __mindspore_signature__ = (
  38. sig.make_sig('x', sig.sig_rw.RW_WRITE, dtype=sig.sig_dtype.T),
  39. sig.make_sig('indices', dtype=sig.sig_dtype.T1),
  40. sig.make_sig('updates', dtype=sig.sig_dtype.T)
  41. )
  42. def _check_scatter_shape(self, x_shape, indices_shape, updates_shape, prim_name):
  43. if indices_shape != [-1] and updates_shape and updates_shape != indices_shape + x_shape[1:]:
  44. raise ValueError(f"For '{prim_name}', "
  45. f"updates_shape = indices_shape + x_shape[1:], but got x_shape: {x_shape}, "
  46. f"indices_shape: {indices_shape}, updates_shape: {updates_shape}.")
  47. @prim_attr_register
  48. def __init__(self, use_locking=False):
  49. """Initialize _ScatterOp"""
  50. validator.check_value_type('use_locking', use_locking, [bool], self.name)
  51. self.init_prim_io_names(inputs=['x', 'indices', 'updates'], outputs=['y'])
  52. self.add_prim_attr('side_effect_mem', True)
  53. def infer_shape(self, x_shape, indices_shape, updates_shape):
  54. self._check_scatter_shape(x_shape, indices_shape, updates_shape, self.name)
  55. return x_shape
  56. def infer_dtype(self, x_dtype, indices_dtype, updates_dtype):
  57. validator.check_tensor_dtype_valid('indices', indices_dtype, [mstype.int32], self.name)
  58. args = {"x": x_dtype, "updates": updates_dtype}
  59. validator.check_tensors_dtypes_same_and_valid(args, mstype.number_type, self.name)
  60. return x_dtype
  61. class _ScatterOp_Dynamic(PrimitiveWithCheck):
  62. """
  63. Defines Scatter operators with dynamic shape
  64. """
  65. __mindspore_signature__ = (
  66. sig.make_sig('x', sig.sig_rw.RW_WRITE, dtype=sig.sig_dtype.T),
  67. sig.make_sig('indices', dtype=sig.sig_dtype.T1),
  68. sig.make_sig('updates', dtype=sig.sig_dtype.T)
  69. )
  70. def _check_scatter_shape(self, x_shape, indices_shape, updates_shape, prim_name):
  71. # x_shape cannot be dynamic
  72. if np.any(np.array(x_shape) == -1):
  73. raise ValueError(f"x does not support dynamic shape")
  74. # support indices and updates dynamic
  75. if np.any(np.array(indices_shape) == -1) or np.any(np.array(updates_shape) == -1):
  76. pass
  77. elif indices_shape != [-1] and updates_shape and updates_shape != indices_shape + x_shape[1:]:
  78. raise ValueError(f"For '{prim_name}', "
  79. f"updates_shape = indices_shape + x_shape[1:], but got x_shape: {x_shape}, "
  80. f"indices_shape: {indices_shape}, updates_shape: {updates_shape}.")
  81. @prim_attr_register
  82. def __init__(self, use_locking=False):
  83. """Initialize _ScatterOp_Dynamic"""
  84. validator.check_value_type('use_locking', use_locking, [bool], self.name)
  85. self.init_prim_io_names(inputs=['x', 'indices', 'updates'], outputs=['y'])
  86. self.add_prim_attr('side_effect_mem', True)
  87. def check_shape(self, x_shape, indices_shape, updates_shape):
  88. self._check_scatter_shape(x_shape, indices_shape, updates_shape, self.name)
  89. def check_dtype(self, x_dtype, indices_dtype, updates_dtype):
  90. validator.check_tensor_dtype_valid('indices', indices_dtype, [mstype.int32], self.name)
  91. args = {"x": x_dtype, "updates": updates_dtype}
  92. validator.check_tensors_dtypes_same_and_valid(args, mstype.number_type, self.name)
  93. class _ScatterNdOp(_ScatterOp):
  94. """
  95. Defines _ScatterNd operators
  96. """
  97. def _check_scatter_shape(self, x_shape, indices_shape, updates_shape, prim_name):
  98. validator.check('the dimension of x', len(x_shape),
  99. 'the dimension of indices', indices_shape[-1], Rel.GE)
  100. if indices_shape[:-1] + x_shape[indices_shape[-1]:] != updates_shape:
  101. raise ValueError(f"For '{prim_name}', updates_shape = "
  102. f"indices_shape[:-1] + x_shape[indices_shape[-1]:], but got x_shape: {x_shape}, "
  103. f"indices_shape: {indices_shape}, updates_shape: {updates_shape}.")
  104. def _check_infer_attr_reduce(axis, keep_dims, prim_name):
  105. validator.check_value_type('keep_dims', keep_dims, [bool], prim_name)
  106. validator.check_value_type('axis', axis, [int, tuple], prim_name)
  107. if isinstance(axis, tuple):
  108. for index, value in enumerate(axis):
  109. validator.check_value_type('axis[%d]' % index, value, [int], prim_name)
  110. class ExpandDims(PrimitiveWithInfer):
  111. """
  112. Adds an additional dimension at the given axis.
  113. Note:
  114. If the specified axis is a negative number, the index is counted
  115. backward from the end and starts at 1.
  116. Inputs:
  117. - **input_x** (Tensor) - The shape of tensor is :math:`(x_1, x_2, ..., x_R)`.
  118. - **axis** (int) - Specifies the dimension index at which to expand
  119. the shape of `input_x`. The value of axis must be in the range
  120. `[-input_x.ndim-1, input_x.ndim]`. Only constant value is allowed.
  121. Outputs:
  122. Tensor, the shape of tensor is :math:`(1, x_1, x_2, ..., x_R)` if the
  123. value of `axis` is 0. It has the same type as `input_x`.
  124. Raises:
  125. ValueError: If `axis` is not an int or not in the valid range.
  126. Supported Platforms:
  127. ``Ascend`` ``GPU`` ``CPU``
  128. Examples:
  129. >>> input_tensor = Tensor(np.array([[2, 2], [2, 2]]), mindspore.float32)
  130. >>> expand_dims = ops.ExpandDims()
  131. >>> output = expand_dims(input_tensor, 0)
  132. >>> print(output)
  133. [[[2. 2.]
  134. [2. 2.]]]
  135. """
  136. @prim_attr_register
  137. def __init__(self):
  138. """Initialize ExpandDims"""
  139. self.init_prim_io_names(inputs=['x', 'axis'], outputs=['output'])
  140. def __infer__(self, x, axis):
  141. validator.check_subclass("x", x['dtype'], mstype.tensor, self.name)
  142. x_shape = list(x['shape'])
  143. axis_v = axis['value']
  144. rank = len(x_shape)
  145. validator.check_int_range(axis_v, -rank - 1, rank, Rel.INC_BOTH, 'axis', self.name)
  146. value = None
  147. if x['value'] is not None:
  148. value = x['value'].asnumpy()
  149. value = np.expand_dims(value, axis_v)
  150. value = Tensor(value)
  151. if axis_v < 0:
  152. axis_v = rank + 1 + axis_v
  153. x_shape.insert(axis_v, 1)
  154. out = {'shape': x_shape,
  155. 'dtype': x['dtype'],
  156. 'value': value}
  157. if 'min_shape' in x and 'max_shape' in x:
  158. out['min_shape'] = x['min_shape']
  159. out['min_shape'].insert(axis_v, 1)
  160. out['max_shape'] = x['max_shape']
  161. out['max_shape'].insert(axis_v, 1)
  162. return out
  163. class DType(PrimitiveWithInfer):
  164. """
  165. Returns the data type of the input tensor as mindspore.dtype.
  166. Inputs:
  167. - **input_x** (Tensor) - The shape of tensor is :math:`(x_1, x_2, ..., x_R)`.
  168. Outputs:
  169. mindspore.dtype, the data type of a tensor.
  170. Raises:
  171. TypeError: If `input_x` is not a Tensor.
  172. Supported Platforms:
  173. ``Ascend`` ``GPU`` ``CPU``
  174. Examples:
  175. >>> input_tensor = Tensor(np.array([[2, 2], [2, 2]]), mindspore.float32)
  176. >>> output = ops.DType()(input_tensor)
  177. >>> print(output)
  178. Float32
  179. """
  180. @prim_attr_register
  181. def __init__(self):
  182. """Initialize DType"""
  183. def __infer__(self, x):
  184. addition_error_info = 'Perhaps you are using a mixture of tensors and scalars to operate.'
  185. validator.check_subclass("input_x", x['dtype'], mstype.tensor, self.name, addition_error_info)
  186. out = {'shape': (),
  187. 'dtype': mstype.type_type,
  188. 'value': x['dtype'].element_type()}
  189. return out
  190. class SameTypeShape(PrimitiveWithInfer):
  191. """
  192. Checks whether the data type and shape of two tensors are the same.
  193. Inputs:
  194. - **input_x** (Tensor) - The shape of tensor is :math:`(x_1, x_2, ..., x_R)`.
  195. - **input_y** (Tensor) - The shape of tensor is :math:`(x_1, x_2, ..., x_S)`.
  196. Outputs:
  197. Tensor, the shape of tensor is :math:`(x_1, x_2, ..., x_R)`,
  198. if data type and shape of `input_x` and `input_y` are the same.
  199. Raises:
  200. TypeError: If the data types of `input_x` and `input_y` are not the same.
  201. ValueError: If the shapes of `input_x` and `input_y` are not the same.
  202. Supported Platforms:
  203. ``Ascend`` ``GPU`` ``CPU``
  204. Examples:
  205. >>> input_x = Tensor(np.array([[2, 2], [2, 2]]), mindspore.float32)
  206. >>> input_y = Tensor(np.array([[2, 2], [2, 2]]), mindspore.float32)
  207. >>> output = ops.SameTypeShape()(input_x, input_y)
  208. >>> print(output)
  209. [[2. 2.]
  210. [2. 2.]]
  211. """
  212. @prim_attr_register
  213. def __init__(self):
  214. """Initialize Same"""
  215. def __call__(self, x, y):
  216. """run in PyNative mode"""
  217. validator.check_value_type('x', x, Tensor, self.name)
  218. validator.check_value_type('y', y, Tensor, self.name)
  219. validator.check('x dtype', x.dtype, 'y dtype', y.dtype, Rel.EQ, self.name, TypeError)
  220. validator.check('x shape', x.shape, 'y shape', y.shape, Rel.EQ, self.name)
  221. return x
  222. def __infer__(self, x, y):
  223. validator.check_subclass('x', x['dtype'], mstype.tensor, self.name)
  224. validator.check_subclass('y', y['dtype'], mstype.tensor, self.name)
  225. validator.check('x dtype', x['dtype'], 'y dtype', y['dtype'], Rel.EQ, self.name, TypeError)
  226. validator.check('x shape', x['shape'], 'y shape', y['shape'], Rel.EQ, self.name)
  227. return x
  228. class Cast(PrimitiveWithInfer):
  229. """
  230. Returns a tensor with the new specified data type.
  231. Inputs:
  232. - **input_x** (Union[Tensor, Number]) - The shape of tensor is :math:`(x_1, x_2, ..., x_R)`.
  233. The tensor to be cast.
  234. - **type** (dtype.Number) - The valid data type of the output tensor. Only constant value is allowed.
  235. Outputs:
  236. Tensor, the shape of tensor is the same as `input_x`, :math:`(x_1, x_2, ..., x_R)`.
  237. Raises:
  238. TypeError: If `input_x` is neither Tensor nor Number.
  239. TypeError: If `type` is not a Number.
  240. Supported Platforms:
  241. ``Ascend`` ``GPU`` ``CPU``
  242. Examples:
  243. >>> input_np = np.random.randn(2, 3, 4, 5).astype(np.float32)
  244. >>> input_x = Tensor(input_np)
  245. >>> type_dst = mindspore.int32
  246. >>> cast = ops.Cast()
  247. >>> output = cast(input_x, type_dst)
  248. >>> print(output.dtype)
  249. Int32
  250. >>> print(output.shape)
  251. (2, 3, 4, 5)
  252. """
  253. @prim_attr_register
  254. def __init__(self):
  255. # if primitive need setattr in __infer__ need add this flag
  256. """Initialize Cast"""
  257. self.init_prim_io_names(inputs=['x', 'dst_type'], outputs=['output'])
  258. def check_elim(self, x, dtype):
  259. if isinstance(x, (Tensor, numbers.Number, Parameter)):
  260. if isinstance(x, Tensor) and x.dtype == dtype:
  261. return (True, x)
  262. if isinstance(x, numbers.Number):
  263. return (True, Tensor(x, dtype=dtype))
  264. if isinstance(x, Parameter):
  265. data = x.data
  266. if data.dtype == dtype:
  267. return (True, x)
  268. return (False, None)
  269. def __infer__(self, x, t):
  270. src_type = x['dtype']
  271. dst_type = t['value']
  272. validator.check_subclass("input_x", src_type, [mstype.tensor, mstype.number], self.name)
  273. validator.check_subclass("type", dst_type, mstype.number, self.name)
  274. if isinstance(src_type, type(mstype.tensor)):
  275. src_type = x['dtype'].element_type()
  276. if isinstance(dst_type, type(mstype.tensor)):
  277. dst_type = dst_type.element_type()
  278. self.add_prim_attr('DstT', dst_type)
  279. self.add_prim_attr('SrcT', src_type)
  280. self.add_prim_attr('dst_type', dst_type)
  281. value = None
  282. if x['value'] is not None:
  283. np_dst_type = mstype.dtype_to_nptype(dst_type)
  284. if isinstance(x['value'], (int, float)):
  285. value = Tensor(np.array(x['value']).astype(np_dst_type))
  286. else:
  287. value = Tensor(x['value'].asnumpy().astype(np_dst_type))
  288. out = {'shape': x['shape'],
  289. 'dtype': mstype.tensor_type(t['value']),
  290. 'value': value}
  291. if 'min_shape' in x and 'max_shape' in x:
  292. out['min_shape'] = x['min_shape']
  293. out['max_shape'] = x['max_shape']
  294. return out
  295. class IsSubClass(PrimitiveWithInfer):
  296. """
  297. Checks whether this type is a sub-class of another type.
  298. Inputs:
  299. - **sub_type** (mindspore.dtype) - The type to be checked. Only constant value is allowed.
  300. - **type_** (mindspore.dtype) - The target type. Only constant value is allowed.
  301. Outputs:
  302. bool, the check result.
  303. Raises:
  304. TypeError: If `sub_type` or `type_` is not a Type.
  305. Supported Platforms:
  306. ``Ascend`` ``GPU`` ``CPU``
  307. Examples:
  308. >>> output = ops.IsSubClass()(mindspore.int32, mindspore.intc)
  309. >>> print(output)
  310. True
  311. """
  312. @prim_attr_register
  313. def __init__(self):
  314. pass
  315. def __infer__(self, sub_type, type_):
  316. sub_type_t = sub_type['value']
  317. type_v = type_['value']
  318. validator.check_value_type("sub_type", sub_type_t, [mstype.Type], self.name)
  319. validator.check_value_type("type_", type_v, [mstype.Type], self.name)
  320. value = mstype.issubclass_(sub_type_t, type_v)
  321. out = {'shape': (),
  322. 'dtype': mstype.type_type,
  323. 'value': value}
  324. return out
  325. class IsInstance(PrimitiveWithInfer):
  326. """
  327. Checks whether an object is an instance of a target type.
  328. Inputs:
  329. - **inst** (Any Object) - The instance to be checked. Only constant value is allowed.
  330. - **type_** (mindspore.dtype) - The target type. Only constant value is allowed.
  331. Outputs:
  332. bool, the check result.
  333. Raises:
  334. TypeError: If `type_` is not a Type.
  335. Supported Platforms:
  336. ``Ascend`` ``GPU`` ``CPU``
  337. Examples:
  338. >>> a = 1
  339. >>> output = ops.IsInstance()(a, mindspore.int32)
  340. >>> print(output)
  341. False
  342. """
  343. @prim_attr_register
  344. def __init__(self):
  345. pass
  346. def __infer__(self, inst, type_):
  347. sub_type_t = inst['dtype']
  348. type_v = type_['value']
  349. validator.check_value_type("type_", type_v, [mstype.Type], self.name)
  350. if type_v == mstype.list_:
  351. value = isinstance(sub_type_t, list)
  352. elif type_v == mstype.tuple_:
  353. value = isinstance(sub_type_t, tuple)
  354. else:
  355. value = mstype.issubclass_(sub_type_t, type_v)
  356. out = {'shape': (),
  357. 'dtype': mstype.type_type,
  358. 'value': value}
  359. return out
  360. class Reshape(PrimitiveWithInfer):
  361. """
  362. Reshapes the input tensor with the same values based on a given shape tuple.
  363. Inputs:
  364. - **input_x** (Tensor) - The shape of tensor is :math:`(x_1, x_2, ..., x_R)`.
  365. - **input_shape** (tuple[int]) - The input tuple is constructed by multiple
  366. integers, i.e., :math:`(y_1, y_2, ..., y_S)`. Only constant value is allowed.
  367. Outputs:
  368. Tensor, the shape of tensor is :math:`(y_1, y_2, ..., y_S)`.
  369. Raises:
  370. ValueError: Given a shape tuple, if it has several -1; or if the product
  371. of its elements is less than or equal to 0 or cannot be divided by the product
  372. of the input tensor shape; or if it does not match the input's array size.
  373. Supported Platforms:
  374. ``Ascend`` ``GPU`` ``CPU``
  375. Examples:
  376. >>> input_tensor = Tensor(np.array([[-0.1, 0.3, 3.6], [0.4, 0.5, -3.2]]), mindspore.float32)
  377. >>> reshape = ops.Reshape()
  378. >>> output = reshape(input_tensor, (3, 2))
  379. >>> print(output)
  380. [[-0.1 0.3]
  381. [ 3.6 0.4]
  382. [ 0.5 -3.2]]
  383. """
  384. @prim_attr_register
  385. def __init__(self):
  386. """Initialize Reshape"""
  387. self.init_prim_io_names(inputs=['tensor', 'shape'], outputs=['output'])
  388. def __infer__(self, x, shape):
  389. shape_v = shape['value']
  390. x_shp = x['shape']
  391. validator.check_subclass("x", x['dtype'], mstype.tensor, self.name)
  392. validator.check_value_type("shape", shape_v, [tuple], self.name)
  393. shape_v = list(shape_v)
  394. neg_index = -1
  395. dim_prod = 1
  396. for i, shp_i in enumerate(shape_v):
  397. validator.check_value_type("shape[%d]" % i, shp_i, [int], self.name)
  398. if shp_i == -1:
  399. if neg_index != -1:
  400. raise ValueError(f'The shape can only has one -1 at most, but {shape_v}.')
  401. neg_index = i
  402. else:
  403. dim_prod *= shp_i
  404. arr_prod = np.prod(x_shp)
  405. if arr_prod <= 0:
  406. if 'max_shape' in x:
  407. x_max_shape = x['max_shape']
  408. else:
  409. x_max_shape = x['shape']
  410. if 'min_shape' in x:
  411. x_min_shape = x['min_shape']
  412. else:
  413. x_min_shape = x['shape']
  414. max_arr_prod = np.prod(x_max_shape)
  415. min_arr_prod = np.prod(x_min_shape)
  416. max_shape = list(shape_v)
  417. min_shape = list(shape_v)
  418. if neg_index != -1:
  419. max_shape[neg_index] = int(max_arr_prod / dim_prod)
  420. min_shape[neg_index] = int(min_arr_prod / dim_prod)
  421. else:
  422. raise ValueError(f'For dynamic shape, Reshape must have neg index')
  423. out = {'shape': shape['value'],
  424. 'dtype': x['dtype'],
  425. 'value': None,
  426. 'max_shape': tuple(max_shape),
  427. 'min_shape': tuple(min_shape)}
  428. else:
  429. if dim_prod <= 0 or arr_prod % dim_prod != 0:
  430. raise ValueError(f'For \'{self.name}\' input_x\'s shape is {x_shp}, input_shape\'s value is {shape_v}.'
  431. f'The product of input_x\'s shape should > 0, '
  432. f'and can be divided by product of input_shape, but '
  433. f'product of input_x\'s shape is {arr_prod}, product of input_shape is {dim_prod}.')
  434. if neg_index != -1:
  435. shape_v[neg_index] = int(arr_prod / dim_prod)
  436. dim_prod *= shape_v[neg_index]
  437. if dim_prod != arr_prod:
  438. raise ValueError(f'For \'{self.name}\' input_x\'s shape is {x_shp}, input_shape\'s value is {shape_v}.'
  439. f'The product of input_x\'s shape should be equal to product of input_shape, but '
  440. f'product of input_x\'s shape is {arr_prod}, product of input_shape is {dim_prod}.')
  441. value = None
  442. if x['value'] is not None:
  443. value = Tensor(x['value'].asnumpy().reshape(shape_v))
  444. out = {'shape': tuple(shape_v),
  445. 'dtype': x['dtype'],
  446. 'value': value}
  447. return out
  448. class Shape(PrimitiveWithInfer):
  449. """
  450. Returns the shape of the input tensor.
  451. Inputs:
  452. - **input_x** (Tensor) - The shape of tensor is :math:`(x_1, x_2, ..., x_R)`.
  453. Outputs:
  454. tuple[int], the output tuple is constructed by multiple integers,
  455. :math:`(x_1, x_2, ..., x_R)`.
  456. Raises:
  457. TypeError: If `input_x` is not a Tensor.
  458. Supported Platforms:
  459. ``Ascend`` ``GPU`` ``CPU``
  460. Examples:
  461. >>> input_tensor = Tensor(np.ones(shape=[3, 2, 1]), mindspore.float32)
  462. >>> shape = ops.Shape()
  463. >>> output = shape(input_tensor)
  464. >>> print(output)
  465. (3, 2, 1)
  466. """
  467. @prim_attr_register
  468. def __init__(self):
  469. """Initialize Shape"""
  470. def __infer__(self, x):
  471. validator.check_subclass("input_x", x['dtype'], mstype.tensor, self.name)
  472. out = {'shape': (),
  473. 'dtype': mstype.tuple_,
  474. 'value': tuple(x['shape'])}
  475. return out
  476. class DynamicShape(Primitive):
  477. """
  478. Returns the shape of the input tensor.
  479. Inputs:
  480. - **input_x** (Tensor) - The shape of tensor is :math:`(x_1, x_2, ..., x_R)`.
  481. Outputs:
  482. Tensor[int], 1-dim Tensor of type int32
  483. Raises:
  484. TypeError: If `input_x` is not a Tensor.
  485. Supported Platforms:
  486. ``Ascend`` ``GPU`` ``CPU``
  487. Examples:
  488. >>> input_tensor = Tensor(np.ones(shape=[3, 2, 1]), mindspore.float32)
  489. >>> shape = ops.DynamicShape()
  490. >>> output = shape(input_tensor)
  491. >>> print(output)
  492. [3 2 1]
  493. """
  494. @prim_attr_register
  495. def __init__(self):
  496. """init Shape"""
  497. self.init_prim_io_names(inputs=['tensor'], outputs=['output'])
  498. self.add_prim_attr('is_dynamic_shape', True)
  499. class Squeeze(PrimitiveWithInfer):
  500. """
  501. Returns a tensor with the same type but dimensions of 1 are removed based on `axis`.
  502. Note:
  503. The dimension index starts at 0 and must be in the range `[-input.ndim, input.ndim`.
  504. Args:
  505. axis (Union[int, tuple(int)]): Specifies the dimension indexes of shape to be removed, which will remove
  506. all the dimensions that are equal to 1. If specified, it must be int32 or int64.
  507. Default: (), an empty tuple.
  508. Inputs:
  509. - **input_x** (Tensor) - The shape of tensor is :math:`(x_1, x_2, ..., x_R)`.
  510. Outputs:
  511. Tensor, the shape of tensor is :math:`(x_1, x_2, ..., x_S)`.
  512. Raises:
  513. TypeError: If `axis` is neither an int nor tuple.
  514. TypeError: If `axis` is a tuple whose elements are not all int.
  515. ValueError: If the corresponding dimension of the specified axis does not equal to 1.
  516. Supported Platforms:
  517. ``Ascend`` ``GPU``
  518. Examples:
  519. >>> input_tensor = Tensor(np.ones(shape=[3, 2, 1]), mindspore.float32)
  520. >>> squeeze = ops.Squeeze(2)
  521. >>> output = squeeze(input_tensor)
  522. >>> print(output)
  523. [[1. 1.]
  524. [1. 1.]
  525. [1. 1.]]
  526. """
  527. @prim_attr_register
  528. def __init__(self, axis=()):
  529. """Initialize Squeeze"""
  530. self.init_prim_io_names(inputs=['x'], outputs=['output'])
  531. validator.check_value_type('axis', axis, [int, tuple], self.name)
  532. if isinstance(axis, tuple):
  533. for idx, item in enumerate(axis):
  534. validator.check_value_type("axis[%d]" % idx, item, [int], self.name)
  535. else:
  536. self.axis = (axis,)
  537. self.add_prim_attr("axis", (axis,))
  538. def infer_shape(self, x_shape):
  539. axis = self.axis
  540. x_shape = list(x_shape)
  541. ndim = len(x_shape)
  542. if not axis:
  543. ret = [d for d in x_shape if d != 1]
  544. else:
  545. for a in axis:
  546. validator.check_int_range(a, -ndim, ndim - 1, Rel.INC_BOTH, 'axis or its elements', self.name)
  547. if x_shape[a] != 1:
  548. raise ValueError('Cannot select an axis to squeeze out which has size not equal to one.')
  549. ret = [x_shape[i] for i in range(ndim) if not (i in axis or (i - ndim) in axis)]
  550. return ret
  551. def infer_dtype(self, x_dtype):
  552. validator.check_subclass("x", x_dtype, mstype.tensor, self.name)
  553. return x_dtype
  554. class Transpose(PrimitiveWithInfer):
  555. """
  556. Permutes the dimensions of the input tensor according to input permutation.
  557. Inputs:
  558. - **input_x** (Tensor) - The shape of tensor is :math:`(x_1, x_2, ..., x_R)`.
  559. - **input_perm** (tuple[int]) - The permutation to be converted. The input tuple is constructed by multiple
  560. indexes. The length of `input_perm` and the shape of `input_x` must be the same. Only constant value is
  561. allowed. Must be in the range [0, rank(input_x)).
  562. Outputs:
  563. Tensor, the type of output tensor is the same as `input_x` and the shape of output tensor is decided by the
  564. shape of `input_x` and the value of `input_perm`.
  565. Raises:
  566. TypeError: If `input_perm` is not a tuple.
  567. ValueError: If length of shape of `input_x` is not equal to length of shape of `input_perm`.
  568. Supported Platforms:
  569. ``Ascend`` ``GPU`` ``CPU``
  570. Examples:
  571. >>> input_tensor = Tensor(np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]), mindspore.float32)
  572. >>> perm = (0, 2, 1)
  573. >>> transpose = ops.Transpose()
  574. >>> output = transpose(input_tensor, perm)
  575. >>> print(output)
  576. [[[ 1. 4.]
  577. [ 2. 5.]
  578. [ 3. 6.]]
  579. [[ 7. 10.]
  580. [ 8. 11.]
  581. [ 9. 12.]]]
  582. """
  583. @prim_attr_register
  584. def __init__(self):
  585. """Initialize Transpose"""
  586. self.init_prim_io_names(inputs=['x', 'perm'], outputs=['output'])
  587. def __infer__(self, x, perm):
  588. x_shape = x['shape']
  589. p_value = perm['value']
  590. x_type = x['dtype']
  591. validator.check_value_type("p_value", p_value, [tuple], self.name)
  592. validator.check_subclass("x_type", x_type, mstype.tensor, self.name)
  593. if len(x_shape) != len(p_value):
  594. raise ValueError('The dimension of x and perm must be equal.')
  595. tmp = list(p_value)
  596. for i, dim in enumerate(p_value):
  597. validator.check_int(dim, 0, Rel.GE, f'perm[{i}]', self.name)
  598. validator.check_int(dim, len(p_value), Rel.LT, f'perm[{i}]', self.name)
  599. tmp.remove(dim)
  600. if dim in tmp:
  601. raise ValueError('The value of perm is wrong.')
  602. out_shapes = []
  603. for i in p_value:
  604. out_shapes.append(x_shape[i])
  605. out = {'shape': tuple(out_shapes),
  606. 'dtype': x['dtype'],
  607. 'value': None}
  608. if 'min_shape' in x and 'max_shape' in x:
  609. min_vec = []
  610. max_vec = []
  611. for i in p_value:
  612. min_vec.append(x['min_shape'][i])
  613. max_vec.append(x['max_shape'][i])
  614. out['min_shape'] = tuple(min_vec)
  615. out['max_shape'] = tuple(max_vec)
  616. return out
  617. class Unique(Primitive):
  618. """
  619. Returns the unique elements of input tensor and also return a tensor containing the index of each value of input
  620. tensor corresponding to the output unique tensor.
  621. Inputs:
  622. - **x** (Tensor) - The input tensor.
  623. Outputs:
  624. Tuple, containing Tensor objects `(y, idx), `y` is a tensor with the
  625. same type as `x`, and contains the unique elements in `x`, sorted in
  626. ascending order. `idx` is a tensor containing indices of elements in
  627. the input corresponding to the output tensor.
  628. Raises:
  629. TypeError: If `x` is not a Tensor.
  630. Supported Platforms:
  631. ``Ascend`` ``GPU`` ``CPU``
  632. Examples:
  633. >>> x = Tensor(np.array([1, 2, 5, 2]), mindspore.int32)
  634. >>> output = ops.Unique()(x)
  635. >>> print(output)
  636. (Tensor(shape=[3], dtype=Int32, value= [1, 2, 5]), Tensor(shape=[4], dtype=Int32, value= [0, 1, 2, 1]))
  637. >>>
  638. >>> # note that for GPU, this operator must be wrapped inside a model, and executed in graph mode.
  639. >>> class UniqueNet(nn.Cell):
  640. ... def __init__(self):
  641. ... super(UniqueNet, self).__init__()
  642. ... self.unique_op = ops.Unique()
  643. ...
  644. ... def construct(self, x):
  645. ... output, indices = self.unique_op(x)
  646. ... return output, indices
  647. ...
  648. >>> x = Tensor(np.array([1, 2, 5, 2]), mindspore.int32)
  649. >>> net = UniqueNet()
  650. >>> output = net(x)
  651. >>> print(output)
  652. (Tensor(shape=[3], dtype=Int32, value= [1, 2, 5]), Tensor(shape=[4], dtype=Int32, value= [0, 1, 2, 1]))
  653. """
  654. @prim_attr_register
  655. def __init__(self):
  656. self.init_prim_io_names(inputs=['x'], outputs=['output'])
  657. class Gather(PrimitiveWithCheck):
  658. """
  659. Returns a slice of the input tensor based on the specified indices and axis.
  660. Inputs:
  661. - **input_params** (Tensor) - The shape of tensor is :math:`(x_1, x_2, ..., x_R)`.
  662. The original Tensor.
  663. - **input_indices** (Tensor) - The shape of tensor is :math:`(y_1, y_2, ..., y_S)`.
  664. Specifies the indices of elements of the original Tensor. Must be in the range
  665. `[0, input_param.shape[axis])`.
  666. - **axis** (int) - Specifies the dimension index to gather indices.
  667. Outputs:
  668. Tensor, the shape of tensor is :math:`(z_1, z_2, ..., z_N)`.
  669. Raises:
  670. TypeError: If `axis` is not an int.
  671. Supported Platforms:
  672. ``Ascend`` ``GPU`` ``CPU``
  673. Examples:
  674. >>> input_params = Tensor(np.array([[1, 2, 7, 42], [3, 4, 54, 22], [2, 2, 55, 3]]), mindspore.float32)
  675. >>> input_indices = Tensor(np.array([1, 2]), mindspore.int32)
  676. >>> axis = 1
  677. >>> output = ops.Gather()(input_params, input_indices, axis)
  678. >>> print(output)
  679. [[ 2. 7.]
  680. [ 4. 54.]
  681. [ 2. 55.]]
  682. """
  683. @prim_attr_register
  684. def __init__(self):
  685. """Initialize index_select"""
  686. self.init_prim_io_names(inputs=['params', 'indices', 'axis'], outputs=['output'])
  687. def __check__(self, params, indices, axis):
  688. validator.check_subclass("params", params['dtype'], mstype.tensor, self.name)
  689. validator.check_tensor_dtype_valid("indices", indices['dtype'], mstype.int_type, self.name)
  690. validator.check_subclass("axis", axis['dtype'], [mstype.number], self.name)
  691. axis_v = axis['value']
  692. validator.check_value_type('axis', axis_v, [int], self.name)
  693. rank = len(params['shape'])
  694. validator.check_int_range(axis_v, -rank, rank, Rel.INC_LEFT, "axis", self.name)
  695. class GatherV2(PrimitiveWithCheck):
  696. """
  697. Same as operator Gather. GatherV2 will be deprecated in the future.
  698. Please use Gather instead.
  699. """
  700. # deprecate_new_name = "Gather"
  701. @deprecated("1.1", "Gather", True)
  702. @prim_attr_register
  703. def __init__(self):
  704. """Initialize index_select"""
  705. self.init_prim_io_names(inputs=['params', 'indices', 'axis'], outputs=['output'])
  706. def __check__(self, params, indices, axis):
  707. validator.check_subclass("params", params['dtype'], mstype.tensor, self.name)
  708. validator.check_tensor_dtype_valid("indices", indices['dtype'], mstype.int_type, self.name)
  709. validator.check_subclass("axis", axis['dtype'], [mstype.number], self.name)
  710. axis_v = axis['value']
  711. validator.check_value_type('axis', axis_v, [int], self.name)
  712. rank = len(params['shape'])
  713. validator.check_int_range(axis_v, -rank, rank, Rel.INC_LEFT, "axis", self.name)
  714. class SparseGatherV2(Gather):
  715. """
  716. Returns a slice of input tensor based on the specified indices and axis.
  717. Inputs:
  718. - **input_params** (Tensor) - The shape of tensor is :math:`(x_1, x_2, ..., x_R)`.
  719. The original Tensor.
  720. - **input_indices** (Tensor) - The shape of tensor is :math:`(y_1, y_2, ..., y_S)`.
  721. Specifies the indices of elements of the original Tensor, must be in the range
  722. `[0, input_param.shape[axis])`.
  723. - **axis** (int) - Specifies the dimension index to gather indices.
  724. Outputs:
  725. Tensor, the shape of tensor is :math:`(z_1, z_2, ..., z_N)`.
  726. Raises:
  727. TypeError: If `axis` is not an int.
  728. Supported Platforms:
  729. ``Ascend`` ``GPU``
  730. Examples:
  731. >>> input_params = Tensor(np.array([[1, 2, 7, 42], [3, 4, 54, 22], [2, 2, 55, 3]]), mindspore.float32)
  732. >>> input_indices = Tensor(np.array([1, 2]), mindspore.int32)
  733. >>> axis = 1
  734. >>> out = ops.SparseGatherV2()(input_params, input_indices, axis)
  735. >>> print(out)
  736. [[2. 7.]
  737. [4. 54.]
  738. [2. 55.]]
  739. """
  740. class Padding(PrimitiveWithInfer):
  741. """
  742. Extends the last dimension of the input tensor from 1 to pad_dim_size, by filling with 0.
  743. Args:
  744. pad_dim_size (int): The value of the last dimension of x to be extended, which must be positive.
  745. Inputs:
  746. - **x** (Tensor) - The shape of tensor is :math:`(x_1, x_2, ..., x_R)`. The rank of x must be at least 2.
  747. The last dimension of x must be 1.
  748. Outputs:
  749. Tensor, the shape of tensor is :math:`(z_1, z_2, ..., z_N)`.
  750. Raises:
  751. TypeError: If `pad_dim_size` is not an int.
  752. ValueError: If `pad_dim_size` is less than 1.
  753. Supported Platforms:
  754. ``Ascend``
  755. Examples:
  756. >>> x = Tensor(np.array([[8], [10]]), mindspore.float32)
  757. >>> pad_dim_size = 4
  758. >>> output = ops.Padding(pad_dim_size)(x)
  759. >>> print(output)
  760. [[ 8. 0. 0. 0.]
  761. [10. 0. 0. 0.]]
  762. """
  763. @prim_attr_register
  764. def __init__(self, pad_dim_size=8):
  765. """Initialize padding"""
  766. validator.check_value_type("pad_dim_size", pad_dim_size, [int], self.name)
  767. validator.check_positive_int(pad_dim_size, "pad_dim_size", self.name)
  768. self.pad_dim_size = pad_dim_size
  769. def __infer__(self, x):
  770. validator.check_subclass("x", x['dtype'], mstype.tensor, self.name)
  771. x_shape = list(x['shape'])
  772. validator.check_int(len(x_shape), 1, Rel.GT, "rank of x", self.name)
  773. validator.check_int(x_shape[-1], 1, Rel.EQ, "last dim of x", self.name)
  774. out_shape = x_shape
  775. out_shape[-1] = self.pad_dim_size
  776. out = {'shape': out_shape,
  777. 'dtype': x['dtype'],
  778. 'value': None}
  779. return out
  780. class UniqueWithPad(PrimitiveWithInfer):
  781. """
  782. Returns unique elements and relative indexes in 1-D tensor, filled with padding num.
  783. Inputs:
  784. - **x** (Tensor) - The tensor need to be unique. Must be 1-D vector with types: int32, int64.
  785. - **pad_num** (int) - Pad num.
  786. Outputs:
  787. tuple(Tensor), tuple of 2 tensors, y and idx.
  788. - y (Tensor) - The unique elements filled with pad_num, the shape and type same as x.
  789. - idx (Tensor) - The index of each value of x in the unique output y, the shape and type same as x.
  790. Raises:
  791. TypeError: If dtype of `x` is neither int32 nor int64.
  792. ValueError: If length of shape of `x` is not equal to 1.
  793. Supported Platforms:
  794. ``Ascend`` ``CPU``
  795. Examples:
  796. >>> x = Tensor(np.array([1, 1, 5, 5, 4, 4, 3, 3, 2, 2,]), mindspore.int32)
  797. >>> pad_num = 8
  798. >>> output = ops.UniqueWithPad()(x, pad_num)
  799. >>> print(output)
  800. (Tensor(shape=[10], dtype=Int32, value= [1, 5, 4, 3, 2, 8, 8, 8, 8, 8]),
  801. Tensor(shape=[10], dtype=Int32, value= [0, 0, 1, 1, 2, 2, 3, 3, 4, 4]))
  802. """
  803. @prim_attr_register
  804. def __init__(self):
  805. """init UniqueWithPad"""
  806. def __infer__(self, x, pad_num):
  807. validator.check_tensor_dtype_valid("x", x['dtype'], [mstype.int32, mstype.int64], self.name)
  808. validator.check_subclass("pad_num", pad_num['dtype'], [mstype.int32, mstype.int64], self.name)
  809. x_shape = list(x['shape'])
  810. validator.check("rank of x", len(x_shape), "expected", 1, Rel.EQ, self.name)
  811. out_shape = x_shape
  812. out = {'shape': (out_shape, out_shape),
  813. 'dtype': (x['dtype'], x['dtype']),
  814. 'value': None}
  815. return out
  816. class Split(PrimitiveWithCheck):
  817. """
  818. Splits the input tensor into output_num of tensors along the given axis and output numbers.
  819. Args:
  820. axis (int): Index of the split position. Default: 0.
  821. output_num (int): The number of output tensors. Must be positive int. Default: 1.
  822. Inputs:
  823. - **input_x** (Tensor) - The shape of tensor is :math:`(x_1, x_2, ..., x_R)`.
  824. Outputs:
  825. tuple[Tensor], the shape of each output tensor is the same, which is
  826. :math:`(y_1, y_2, ..., y_S)`.
  827. Raises:
  828. TypeError: If `axis` or `output_num` is not an int.
  829. ValueError: If `axis` is out of the range [-len(`input_x.shape`), len(`input_x.shape`)),
  830. or if the `output_num` is less than or equal to 0.
  831. Supported Platforms:
  832. ``Ascend`` ``GPU`` ``CPU``
  833. Examples:
  834. >>> split = ops.Split(1, 2)
  835. >>> x = Tensor(np.array([[1, 1, 1, 1], [2, 2, 2, 2]]), mindspore.int32)
  836. >>> output = split(x)
  837. >>> print(output)
  838. (Tensor(shape=[2, 2], dtype=Int32, value=
  839. [[1, 1],
  840. [2, 2]]), Tensor(shape=[2, 2], dtype=Int32, value=
  841. [[1, 1],
  842. [2, 2]]))
  843. """
  844. @prim_attr_register
  845. def __init__(self, axis=0, output_num=1):
  846. """Initialize Split"""
  847. validator.check_value_type("axis", axis, [int], self.name)
  848. validator.check_value_type("output_num", output_num, [int], self.name)
  849. validator.check_positive_int(output_num, "output_num", self.name)
  850. self.axis = axis
  851. self.output_num = output_num
  852. def __check__(self, x):
  853. validator.check_subclass("x", x['dtype'], mstype.tensor, self.name)
  854. x_shape = list(x['shape'])
  855. dim = len(x_shape)
  856. validator.check_int_range(self.axis, -dim, dim, Rel.INC_LEFT, 'axis value', self.name)
  857. if -1 not in x_shape:
  858. # only validate when shape fully known
  859. output_valid_check = x_shape[self.axis] % self.output_num
  860. if output_valid_check != 0:
  861. raise ValueError(f"x_shape[{self.axis}] {x_shape[self.axis]} must be divide exactly by"
  862. f" output_num {self.output_num}")
  863. size_splits = [x_shape[self.axis] // self.output_num] * self.output_num
  864. self.add_prim_attr('size_splits', size_splits)
  865. class Rank(PrimitiveWithInfer):
  866. """
  867. Returns the rank of a tensor.
  868. Returns a 0-D int32 Tensor representing the rank of input; the rank of a tensor
  869. is the number of indices required to uniquely select each element of the tensor.
  870. Inputs:
  871. - **input_x** (Tensor) - The shape of tensor is :math:`(x_1, x_2, ..., x_R)`.
  872. Outputs:
  873. Tensor. 0-D int32 Tensor representing the rank of input, i.e., :math:`R`.
  874. Raises:
  875. TypeError: If `input_x` is not a Tensor.
  876. Supported Platforms:
  877. ``Ascend`` ``GPU`` ``CPU``
  878. Examples:
  879. >>> input_tensor = Tensor(np.array([[2, 2], [2, 2]]), mindspore.float32)
  880. >>> rank = ops.Rank()
  881. >>> output = rank(input_tensor)
  882. >>> print(output)
  883. 2
  884. """
  885. @prim_attr_register
  886. def __init__(self):
  887. """Initialize Rank"""
  888. def __infer__(self, x):
  889. validator.check_subclass("x", x['dtype'], mstype.tensor, self.name)
  890. out = {'shape': None,
  891. 'dtype': None,
  892. 'value': len(x['shape'])}
  893. return out
  894. class TruncatedNormal(PrimitiveWithInfer):
  895. """
  896. Returns a tensor of the specified shape filled with truncated normal values.
  897. The generated values follow a normal distribution.
  898. Args:
  899. seed (int): A integer number used to create random seed. Default: 0.
  900. dtype (:class:`mindspore.dtype`): Data type. Default: mindspore.float32.
  901. Inputs:
  902. - **shape** (tuple[int]) - The shape of the output tensor, is a tuple of positive integer.
  903. Outputs:
  904. Tensor, the data type of output tensor is the same as attribute `dtype`.
  905. Examples:
  906. >>> shape = (1, 2, 3)
  907. >>> truncated_normal = ops.TruncatedNormal()
  908. >>> output = truncated_normal(shape)
  909. """
  910. @prim_attr_register
  911. def __init__(self, seed=0, dtype=mstype.float32):
  912. """Initialize TruncatedNormal"""
  913. validator.check_value_type('seed', seed, [int], self.name)
  914. validator.check_types_same_and_valid({'dtype': dtype}, mstype.number_type, self.name)
  915. def __infer__(self, shape):
  916. shape_value = shape['value']
  917. validator.check_value_type("shape", shape_value, [tuple], self.name)
  918. for i, value in enumerate(shape_value):
  919. validator.check_positive_int(value, f'{i}th value of shape', self.name)
  920. out = {'shape': shape_value,
  921. 'dtype': mstype.tensor_type(self.dtype),
  922. 'value': None}
  923. return out
  924. class Size(PrimitiveWithInfer):
  925. r"""
  926. Returns the size of a tensor.
  927. Returns an int scalar representing the elements size of input, the total number of elements in the tensor.
  928. Inputs:
  929. - **input_x** (Tensor) - The shape of tensor is :math:`(x_1, x_2, ..., x_R)`.
  930. Outputs:
  931. int, a scalar representing the elements size of `input_x`, tensor is the number of elements
  932. in a tensor, :math:`size=x_1*x_2*...x_R`.
  933. Raises:
  934. TypeError: If `input_x` is not a Tensor.
  935. Supported Platforms:
  936. ``Ascend`` ``GPU`` ``CPU``
  937. Examples:
  938. >>> input_tensor = Tensor(np.array([[2, 2], [2, 2]]), mindspore.float32)
  939. >>> size = ops.Size()
  940. >>> output = size(input_tensor)
  941. >>> print(output)
  942. 4
  943. """
  944. @prim_attr_register
  945. def __init__(self):
  946. """Initialize Size"""
  947. def __infer__(self, x):
  948. size = 1
  949. validator.check_subclass("x", x['dtype'], mstype.tensor, self.name)
  950. shp = x['shape']
  951. if not shp:
  952. size = 0
  953. else:
  954. size = functools.reduce(lambda x, y: x * y, x['shape'])
  955. out = {'shape': None,
  956. 'dtype': mstype.int32,
  957. 'value': size}
  958. return out
  959. class Fill(PrimitiveWithInfer):
  960. """
  961. Creates a tensor filled with a scalar value.
  962. Creates a tensor with shape described by the first argument and fills it with values in the second argument.
  963. Inputs:
  964. - **type** (mindspore.dtype) - The specified type of output tensor. Only constant value is allowed.
  965. - **shape** (tuple) - The specified shape of output tensor. Only constant value is allowed.
  966. - **value** (scalar) - Value to fill the returned tensor. Only constant value is allowed.
  967. Outputs:
  968. Tensor, has the same type and shape as input value.
  969. Raises:
  970. TypeError: If `shape` is not a tuple.
  971. Supported Platforms:
  972. ``Ascend`` ``GPU`` ``CPU``
  973. Examples:
  974. >>> fill = ops.Fill()
  975. >>> output = fill(mindspore.float32, (2, 2), 1)
  976. >>> print(output)
  977. [[1. 1.]
  978. [1. 1.]]
  979. """
  980. @prim_attr_register
  981. def __init__(self):
  982. """Initialize Fill"""
  983. def __infer__(self, dtype, dims, x):
  984. validator.check_value_type("shape", dims['value'], [tuple], self.name)
  985. validator.check_value_type("value", x['value'], [numbers.Number, bool], self.name)
  986. for i, item in enumerate(dims['value']):
  987. validator.check_positive_int(item, f'dims[{i}]', self.name)
  988. valid_dtypes = [mstype.bool_, mstype.int8, mstype.int16, mstype.int32, mstype.int64,
  989. mstype.uint8, mstype.uint16, mstype.uint32, mstype.uint64,
  990. mstype.float16, mstype.float32, mstype.float64]
  991. validator.check_types_same_and_valid({"value": dtype['value']}, valid_dtypes, self.name)
  992. x_nptype = mstype.dtype_to_nptype(dtype['value'])
  993. ret = np.full(dims['value'], x['value'], x_nptype)
  994. out = {
  995. 'value': Tensor(ret),
  996. 'shape': dims['value'],
  997. 'dtype': x['dtype'],
  998. }
  999. return out
  1000. class Ones(PrimitiveWithInfer):
  1001. r"""
  1002. Creates a tensor filled with value ones.
  1003. Creates a tensor with shape described by the first argument and
  1004. fills it with value ones in type of the second argument.
  1005. Inputs:
  1006. - **shape** (Union[tuple[int], int]) - The specified shape of output tensor.
  1007. Only constant positive int is allowed.
  1008. - **type** (mindspore.dtype) - The specified type of output tensor. Only constant value is allowed.
  1009. Outputs:
  1010. Tensor, has the same type and shape as input shape value.
  1011. Raises:
  1012. TypeError: If `shape` is neither tuple nor int.
  1013. Supported Platforms:
  1014. ``Ascend`` ``GPU`` ``CPU``
  1015. Examples:
  1016. >>> from mindspore.ops import operations as ops
  1017. >>> ones = ops.Ones()
  1018. >>> output = ones((2, 2), mindspore.float32)
  1019. >>> print(output)
  1020. [[1. 1.]
  1021. [1. 1.]]
  1022. """
  1023. @prim_attr_register
  1024. def __init__(self):
  1025. """Initialize Ones"""
  1026. def __infer__(self, dims, dtype):
  1027. if isinstance(dims['value'], int):
  1028. shape = (dims['value'],)
  1029. else:
  1030. shape = dims['value']
  1031. validator.check_value_type("shape", shape, [tuple], self.name)
  1032. for i, item in enumerate(shape):
  1033. validator.check_non_negative_int(item, shape[i], self.name)
  1034. valid_types = [mstype.bool_, mstype.int8, mstype.int16, mstype.int32, mstype.int64,
  1035. mstype.uint8, mstype.uint16, mstype.uint32, mstype.uint64,
  1036. mstype.float16, mstype.float32, mstype.float64]
  1037. validator.check_types_same_and_valid({"value": dtype['value']}, valid_types, self.name)
  1038. x_nptype = mstype.dtype_to_nptype(dtype['value'])
  1039. ret = np.ones(shape, x_nptype)
  1040. out = {
  1041. 'value': Tensor(ret),
  1042. 'shape': shape,
  1043. 'dtype': x_nptype,
  1044. }
  1045. return out
  1046. class Zeros(PrimitiveWithInfer):
  1047. r"""
  1048. Creates a tensor filled with value zeros.
  1049. Creates a tensor with shape described by the first argument and
  1050. fills it with value zeros in type of the second argument.
  1051. Inputs:
  1052. - **shape** (Union[tuple[int], int]) - The specified shape of output tensor.
  1053. Only constant positive int is allowed.
  1054. - **type** (mindspore.dtype) - The specified type of output tensor. Only constant value is allowed.
  1055. Outputs:
  1056. Tensor, has the same type and shape as input shape value.
  1057. Raises:
  1058. TypeError: If `shape` is neither int nor tuple.
  1059. TypeError: If `shape` is a tuple whose elements are not all int.
  1060. Supported Platforms:
  1061. ``Ascend`` ``GPU`` ``CPU``
  1062. Examples:
  1063. >>> from mindspore.ops import operations as ops
  1064. >>> zeros = ops.Zeros()
  1065. >>> output = zeros((2, 2), mindspore.float32)
  1066. >>> print(output)
  1067. [[0. 0.]
  1068. [0. 0.]]
  1069. """
  1070. @prim_attr_register
  1071. def __init__(self):
  1072. """Initialize Zeros"""
  1073. def __infer__(self, dims, dtype):
  1074. if isinstance(dims['value'], int):
  1075. shape = (dims['value'],)
  1076. else:
  1077. shape = dims['value']
  1078. validator.check_value_type("shape", shape, [tuple], self.name)
  1079. for i, item in enumerate(shape):
  1080. validator.check_non_negative_int(item, shape[i], self.name)
  1081. valid_types = [mstype.bool_, mstype.int8, mstype.int16, mstype.int32, mstype.int64,
  1082. mstype.uint8, mstype.uint16, mstype.uint32, mstype.uint64,
  1083. mstype.float16, mstype.float32, mstype.float64]
  1084. validator.check_types_same_and_valid({"value": dtype['value']}, valid_types, self.name)
  1085. x_nptype = mstype.dtype_to_nptype(dtype['value'])
  1086. ret = np.zeros(shape, x_nptype)
  1087. out = {
  1088. 'value': Tensor(ret),
  1089. 'shape': shape,
  1090. 'dtype': x_nptype,
  1091. }
  1092. return out
  1093. class OnesLike(PrimitiveWithInfer):
  1094. """
  1095. Creates a new tensor. The values of all elements are 1.
  1096. Returns a tensor of ones with the same shape and type as the input.
  1097. Inputs:
  1098. - **input_x** (Tensor) - Input tensor.
  1099. Outputs:
  1100. Tensor, has the same shape and type as `input_x` but filled with ones.
  1101. Raises:
  1102. TypeError: If `input_x` is not a Tensor.
  1103. Supported Platforms:
  1104. ``Ascend`` ``GPU`` ``CPU``
  1105. Examples:
  1106. >>> oneslike = ops.OnesLike()
  1107. >>> x = Tensor(np.array([[0, 1], [2, 1]]).astype(np.int32))
  1108. >>> output = oneslike(x)
  1109. >>> print(output)
  1110. [[1 1]
  1111. [1 1]]
  1112. """
  1113. @prim_attr_register
  1114. def __init__(self):
  1115. """Initialize OnesLike"""
  1116. def infer_shape(self, x_shape):
  1117. return x_shape
  1118. def infer_dtype(self, x_dtype):
  1119. validator.check_tensor_dtype_valid('x', x_dtype, mstype.number_type + (mstype.bool_,), self.name)
  1120. return x_dtype
  1121. class ZerosLike(PrimitiveWithCheck):
  1122. """
  1123. Creates a new tensor. All elements value are 0.
  1124. Returns a tensor of zeros with the same shape and data type as the input tensor.
  1125. Inputs:
  1126. - **input_x** (Tensor) - Input tensor.
  1127. Outputs:
  1128. Tensor, has the same shape and data type as `input_x` but filled with zeros.
  1129. Raises:
  1130. TypeError: If `input_x` is not a Tensor.
  1131. Supported Platforms:
  1132. ``Ascend`` ``GPU`` ``CPU``
  1133. Examples:
  1134. >>> zeroslike = ops.ZerosLike()
  1135. >>> x = Tensor(np.array([[0, 1], [2, 1]]).astype(np.float32))
  1136. >>> output = zeroslike(x)
  1137. >>> print(output)
  1138. [[0. 0.]
  1139. [0. 0.]]
  1140. """
  1141. @prim_attr_register
  1142. def __init__(self):
  1143. """Initialize ZerosLike"""
  1144. self.init_prim_io_names(inputs=['x'], outputs=['y'])
  1145. def check_dtype(self, x_dtype):
  1146. validator.check_tensor_dtype_valid('x', x_dtype, mstype.number_type + (mstype.bool_,), self.name)
  1147. class TupleToArray(PrimitiveWithInfer):
  1148. """
  1149. Converts a tuple to a tensor.
  1150. If the type of the first number in the tuple is integer, the data type of the output tensor is int.
  1151. Otherwise, the data type of the output tensor is float.
  1152. Inputs:
  1153. - **input_x** (tuple) - A tuple of numbers. These numbers have the same type. Only constant value is allowed.
  1154. Outputs:
  1155. Tensor, if the input tuple contains `N` numbers, then the shape of the output tensor is (N,).
  1156. Raises:
  1157. TypeError: If `input_x` is not a tuple.
  1158. ValueError: If length of `input_x` is less than or equal to 0.
  1159. Supported Platforms:
  1160. ``Ascend`` ``GPU`` ``CPU``
  1161. Examples:
  1162. >>> type = ops.TupleToArray()((1,2,3))
  1163. >>> print(type)
  1164. [1 2 3]
  1165. """
  1166. @prim_attr_register
  1167. def __init__(self):
  1168. """Initialize TupleToArray"""
  1169. def infer_value(self, x):
  1170. validator.check_value_type("x", x, [tuple], self.name)
  1171. validator.check("size of x", len(x), '', 0, Rel.GT, self.name)
  1172. dtype = type(x[0])
  1173. for i, item in enumerate(x):
  1174. validator.check_value_type(f"x[{i}]", item, [numbers.Number], self.name)
  1175. if not all(isinstance(item, dtype) for item in x):
  1176. raise TypeError("For \'{self.name}\' all elements of input x must be have same type.")
  1177. if isinstance(x[0], int):
  1178. ret = np.array(x, np.int32)
  1179. else:
  1180. ret = np.array(x, np.float32)
  1181. return Tensor(ret)
  1182. def __call__(self, x):
  1183. args = list()
  1184. if isinstance(x, range):
  1185. args.append(tuple(x))
  1186. else:
  1187. args.append(x)
  1188. return _run_op(self, self.name, args)
  1189. class ScalarToArray(PrimitiveWithInfer):
  1190. """
  1191. Converts a scalar to a `Tensor`.
  1192. Inputs:
  1193. - **input_x** (Union[int, float]) - The input is a scalar. Only constant value is allowed.
  1194. Outputs:
  1195. Tensor. 0-D Tensor and the content is the input.
  1196. Raises:
  1197. TypeError: If `input_x` is neither int nor float.
  1198. Supported Platforms:
  1199. ``Ascend`` ``GPU`` ``CPU``
  1200. Examples:
  1201. >>> op = ops.ScalarToArray()
  1202. >>> data = 1.0
  1203. >>> output = op(data)
  1204. >>> print(output)
  1205. 1.0
  1206. """
  1207. @prim_attr_register
  1208. def __init__(self):
  1209. pass
  1210. def infer_value(self, x):
  1211. validator.check_value_type("x", x, [int, float], self.name)
  1212. if isinstance(x, int):
  1213. ret = np.array(x, np.int32)
  1214. else:
  1215. ret = np.array(x, np.float32)
  1216. return Tensor(ret)
  1217. class ScalarToTensor(PrimitiveWithInfer):
  1218. """
  1219. Converts a scalar to a `Tensor`, and converts the data type to the specified type.
  1220. Inputs:
  1221. - **input_x** (Union[int, float]) - The input is a scalar. Only constant value is allowed.
  1222. - **dtype** (mindspore.dtype) - The target data type. Default: mindspore.float32. Only
  1223. constant value is allowed.
  1224. Outputs:
  1225. Tensor. 0-D Tensor and the content is the input.
  1226. Raises:
  1227. TypeError: If `input_x` is neither int nor float.
  1228. Supported Platforms:
  1229. ``Ascend`` ``GPU`` ``CPU``
  1230. Examples:
  1231. >>> op = ops.ScalarToTensor()
  1232. >>> data = 1
  1233. >>> output = op(data, mindspore.float32)
  1234. >>> print(output)
  1235. 1.0
  1236. """
  1237. @prim_attr_register
  1238. def __init__(self):
  1239. pass
  1240. def infer_value(self, x, dtype=mstype.float32):
  1241. validator.check_value_type("x", x, [int, float], self.name)
  1242. validator.check_subclass("dtype", dtype, mstype.number, self.name)
  1243. data_type = mstype.dtype_to_nptype(dtype)
  1244. return Tensor(np.array(x, data_type))
  1245. class InvertPermutation(PrimitiveWithInfer):
  1246. r"""
  1247. Computes the inverse of an index permutation.
  1248. Given a tuple input, this operation inserts a dimension of 1 at the dimension
  1249. This operation calculates the inverse of the index replacement. It requires a
  1250. 1-dimensional tuple x, which represents the array starting at zero,
  1251. and swaps each value with its index position. In other words, for the output
  1252. tuple y and the input tuple x, this operation calculates the following:
  1253. :math:`y[x[i]] = i, \quad i \in [0, 1, \ldots, \text{len}(x)-1]`.
  1254. Note:
  1255. These values must include 0. There must be no duplicate values and the
  1256. values can not be negative.
  1257. Inputs:
  1258. - **input_x** (Union(tuple[int], list[int]) - The input is constructed by multiple
  1259. integers, i.e., :math:`(y_1, y_2, ..., y_S)` representing the indices.
  1260. The values must include 0. There can be no duplicate values or negative values.
  1261. Only constant value is allowed. The maximum value must be equal to length of input_x.
  1262. Outputs:
  1263. tuple[int]. It has the same length as the input.
  1264. Raises:
  1265. TypeError: If `input_x` is neither tuple nor list.
  1266. TypeError: If element of `input_x` is not an int.
  1267. Supported Platforms:
  1268. ``Ascend`` ``GPU`` ``CPU``
  1269. Examples:
  1270. >>> invert = ops.InvertPermutation()
  1271. >>> input_data = (3, 4, 0, 2, 1)
  1272. >>> output = invert(input_data)
  1273. >>> print(output)
  1274. (2, 4, 3, 0, 1)
  1275. """
  1276. @prim_attr_register
  1277. def __init__(self):
  1278. """Initialize InvertPermutation"""
  1279. self.set_const_prim(True)
  1280. def __infer__(self, x):
  1281. x_shp = x['shape']
  1282. x_value = x['value']
  1283. if x_value is None:
  1284. raise ValueError(f'For \'{self.name}\' the input value must be const.')
  1285. validator.check_value_type("shape", x_shp, [tuple, list], self.name)
  1286. if mstype.issubclass_(x['dtype'], mstype.tensor):
  1287. raise ValueError(f'For \'{self.name}\' the input value must be non-Tensor.')
  1288. for shp in x_shp:
  1289. if shp != []:
  1290. x_rank = len(np.array(x_value, np.int64).shape)
  1291. raise ValueError(f'For \'{self.name}\' the rank of input must be 1, but got {x_rank}.')
  1292. for i, value in enumerate(x_value):
  1293. validator.check_value_type("input[%d]" % i, value, [int], self.name)
  1294. z = [x_value[i] for i in range(len(x_value))]
  1295. z.sort()
  1296. for i in range(1, len(z)):
  1297. if z[i - 1] == z[i]:
  1298. raise ValueError(f"For {self.name}, {z[i]} is duplicated in the input.")
  1299. validator.check(f'value min', min(x_value), '', 0, Rel.EQ, self.name)
  1300. validator.check(f'value max', max(x_value), '', len(x_value) - 1, Rel.EQ, self.name)
  1301. y = [None] * len(x_value)
  1302. for i, value in enumerate(x_value):
  1303. validator.check_value_type("input[%d]" % i, value, [int], self.name)
  1304. validator.check(f'value', z[i], f'index', i, Rel.EQ, self.name)
  1305. y[value] = i
  1306. z.append(value)
  1307. return {'shape': x_shp,
  1308. 'dtype': x['dtype'],
  1309. 'value': tuple(y)}
  1310. class Argmax(PrimitiveWithInfer):
  1311. """
  1312. Returns the indices of the maximum value of a tensor across the axis.
  1313. If the shape of input tensor is :math:`(x_1, ..., x_N)`, the shape of the output tensor will be
  1314. :math:`(x_1, ..., x_{axis-1}, x_{axis+1}, ..., x_N)`.
  1315. Args:
  1316. axis (int): Axis where the Argmax operation applies to. Default: -1.
  1317. output_type (:class:`mindspore.dtype`): An optional data type of `mindspore.dtype.int32`.
  1318. Default: `mindspore.dtype.int32`.
  1319. Inputs:
  1320. - **input_x** (Tensor) - Input tensor.
  1321. Outputs:
  1322. Tensor, indices of the max value of input tensor across the axis.
  1323. Raises:
  1324. TypeError: If `axis` is not an int.
  1325. TypeError: If `output_type` is neither int32 nor int64.
  1326. Supported Platforms:
  1327. ``Ascend`` ``GPU`` ``CPU``
  1328. Examples:
  1329. >>> input_x = Tensor(np.array([[1, 20, 5], [67, 8, 9], [130, 24, 15]]).astype(np.float32))
  1330. >>> output = ops.Argmax(output_type=mindspore.int32)(input_x)
  1331. >>> print(output)
  1332. [1 0 0]
  1333. """
  1334. @prim_attr_register
  1335. def __init__(self, axis=-1, output_type=mstype.int32):
  1336. """Initialize Argmax"""
  1337. self.init_prim_io_names(inputs=['x'], outputs=['output'])
  1338. validator.check_value_type("axis", axis, [int], self.name)
  1339. validator.check_types_same_and_valid({'output': output_type}, [mstype.int32], self.name)
  1340. self.axis = axis
  1341. self.add_prim_attr('output_type', output_type)
  1342. def infer_shape(self, x_shape):
  1343. axis = self.axis
  1344. if axis is None:
  1345. axis = 0
  1346. x_rank = len(x_shape)
  1347. validator.check_int_range(axis, -x_rank, x_rank, Rel.INC_LEFT, "axis", self.name)
  1348. axis = axis + x_rank if axis < 0 else axis
  1349. ouput_shape = [x_shape[i] for i in range(x_rank) if i != axis]
  1350. return ouput_shape
  1351. def infer_dtype(self, x_dtype):
  1352. validator.check_subclass("input_x", x_dtype, mstype.tensor, self.name)
  1353. return mstype.tensor_type(self.output_type)
  1354. class Argmin(PrimitiveWithInfer):
  1355. """
  1356. Returns the indices of the minimum value of a tensor across the axis.
  1357. If the shape of input tensor is :math:`(x_1, ..., x_N)`, the shape of the output tensor is
  1358. :math:`(x_1, ..., x_{axis-1}, x_{axis+1}, ..., x_N)`.
  1359. Args:
  1360. axis (int): Axis where the Argmin operation applies to. Default: -1.
  1361. output_type (:class:`mindspore.dtype`): An optional data type of `mindspore.dtype.int32`.
  1362. Default: `mindspore.dtype.int32`.
  1363. Inputs:
  1364. - **input_x** (Tensor) - Input tensor.
  1365. Outputs:
  1366. Tensor, indices of the min value of input tensor across the axis.
  1367. Raises:
  1368. TypeError: If `axis` is not an int.
  1369. TypeError: If `output_type` is neither int32 nor int64.
  1370. Supported Platforms:
  1371. ``Ascend``
  1372. Examples:
  1373. >>> input_x = Tensor(np.array([2.0, 3.1, 1.2]), mindspore.float32)
  1374. >>> index = ops.Argmin()(input_x)
  1375. >>> print(index)
  1376. 2
  1377. """
  1378. @prim_attr_register
  1379. def __init__(self, axis=-1, output_type=mstype.int32):
  1380. """Initialize Argmin"""
  1381. self.init_prim_io_names(inputs=['x'], outputs=['output'])
  1382. validator.check_value_type("axis", axis, [int], self.name)
  1383. validator.check_type_name("output_type", output_type, [mstype.int32, mstype.int64], self.name)
  1384. self.axis = axis
  1385. self.add_prim_attr('output_type', output_type)
  1386. def infer_shape(self, x_shape):
  1387. axis = self.axis
  1388. if axis is None:
  1389. axis = 0
  1390. x_rank = len(x_shape)
  1391. validator.check_int_range(axis, -x_rank, x_rank, Rel.INC_LEFT, "axis", self.name)
  1392. axis = axis + x_rank if axis < 0 else axis
  1393. ouput_shape = [x_shape[i] for i in range(x_rank) if i != axis]
  1394. return ouput_shape
  1395. def infer_dtype(self, x_dtype):
  1396. validator.check_subclass("input_x", x_dtype, mstype.tensor, self.name)
  1397. return mstype.tensor_type(self.output_type)
  1398. class ArgMaxWithValue(PrimitiveWithInfer):
  1399. """
  1400. Calculates the maximum value with the corresponding index.
  1401. Calculates the maximum value along with the given axis for the input tensor. It returns the maximum values and
  1402. indices.
  1403. Note:
  1404. In auto_parallel and semi_auto_parallel mode, the first output index can not be used.
  1405. Args:
  1406. axis (int): The dimension to reduce. Default: 0.
  1407. keep_dims (bool): Whether to reduce dimension, if true, the output will keep same dimension with the input,
  1408. the output will reduce dimension if false. Default: False.
  1409. Inputs:
  1410. - **input_x** (Tensor) - The input tensor, can be any dimension. Set the shape of input tensor as
  1411. :math:`(x_1, x_2, ..., x_N)`.
  1412. Outputs:
  1413. tuple (Tensor), tuple of 2 tensors, containing the corresponding index and the maximum value of the input
  1414. tensor.
  1415. - index (Tensor) - The index for the maximum value of the input tensor. If `keep_dims` is true, the shape of
  1416. output tensors is :math:`(x_1, x_2, ..., x_{axis-1}, 1, x_{axis+1}, ..., x_N)`. Otherwise, the shape is
  1417. :math:`(x_1, x_2, ..., x_{axis-1}, x_{axis+1}, ..., x_N)`.
  1418. - output_x (Tensor) - The maximum value of input tensor, with the same shape as index.
  1419. Raises:
  1420. TypeError: If `keep_dims` is not a bool.
  1421. TypeError: If `axis` is not an int.
  1422. Supported Platforms:
  1423. ``Ascend`` ``GPU``
  1424. Examples:
  1425. >>> input_x = Tensor(np.array([0.0, 0.4, 0.6, 0.7, 0.1]), mindspore.float32)
  1426. >>> index, output = ops.ArgMaxWithValue()(input_x)
  1427. >>> print(index, output)
  1428. 3 0.7
  1429. """
  1430. @prim_attr_register
  1431. def __init__(self, axis=0, keep_dims=False):
  1432. """Initialize ArgMaxWithValue"""
  1433. self.axis = axis
  1434. self.keep_dims = keep_dims
  1435. validator.check_value_type('keep_dims', keep_dims, [bool], self.name)
  1436. validator.check_value_type('axis', axis, [int], self.name)
  1437. def infer_shape(self, x_shape):
  1438. axis = self.axis
  1439. x_rank = len(x_shape)
  1440. validator.check_int_range(axis, -x_rank, x_rank, Rel.INC_LEFT, "axis", self.name)
  1441. ouput_shape = _infer_shape_reduce(x_shape, self.axis, self.keep_dims, self.name)
  1442. return ouput_shape, ouput_shape
  1443. def infer_dtype(self, x_dtype):
  1444. validator.check_subclass("input_x", x_dtype, mstype.tensor, self.name)
  1445. return mstype.tensor_type(mstype.int32), x_dtype
  1446. class ArgMinWithValue(PrimitiveWithInfer):
  1447. """
  1448. Calculates the minimum value with corresponding index, and returns indices and values.
  1449. Calculates the minimum value along with the given axis for the input tensor. It returns the minimum values and
  1450. indices.
  1451. Note:
  1452. In auto_parallel and semi_auto_parallel mode, the first output index can not be used.
  1453. Args:
  1454. axis (int): The dimension to reduce. Default: 0.
  1455. keep_dims (bool): Whether to reduce dimension, if true the output will keep the same dimension as the input,
  1456. the output will reduce dimension if false. Default: False.
  1457. Inputs:
  1458. - **input_x** (Tensor) - The input tensor, can be any dimension. Set the shape of input tensor as
  1459. :math:`(x_1, x_2, ..., x_N)`.
  1460. Outputs:
  1461. tuple (Tensor), tuple of 2 tensors, containing the corresponding index and the minimum value of the input
  1462. tensor.
  1463. - index (Tensor) - The index for the minimum value of the input tensor. If `keep_dims` is true, the shape of
  1464. output tensors is :math:`(x_1, x_2, ..., x_{axis-1}, 1, x_{axis+1}, ..., x_N)`. Otherwise, the shape is
  1465. :math:`(x_1, x_2, ..., x_{axis-1}, x_{axis+1}, ..., x_N)`.
  1466. - output_x (Tensor) - The minimum value of input tensor, with the same shape as index.
  1467. Raises:
  1468. TypeError: If `keep_dims` is not a bool.
  1469. TypeError: If `axis` is not an int.
  1470. Supported Platforms:
  1471. ``Ascend`` ``CPU``
  1472. Examples:
  1473. >>> input_x = Tensor(np.array([0.0, 0.4, 0.6, 0.7, 0.1]), mindspore.float32)
  1474. >>> output = ops.ArgMinWithValue()(input_x)
  1475. >>> print(output)
  1476. (Tensor(shape=[], dtype=Int32, value= 0), Tensor(shape=[], dtype=Float32, value= 0.0))
  1477. """
  1478. @prim_attr_register
  1479. def __init__(self, axis=0, keep_dims=False):
  1480. """Initialize ArgMinWithValue"""
  1481. self.axis = axis
  1482. self.keep_dims = keep_dims
  1483. validator.check_value_type('keep_dims', keep_dims, [bool], self.name)
  1484. validator.check_value_type('axis', axis, [int], self.name)
  1485. def infer_shape(self, x_shape):
  1486. axis = self.axis
  1487. x_rank = len(x_shape)
  1488. validator.check_int_range(axis, -x_rank, x_rank, Rel.INC_LEFT, "axis", self.name)
  1489. ouput_shape = _infer_shape_reduce(x_shape, self.axis, self.keep_dims, self.name)
  1490. return ouput_shape, ouput_shape
  1491. def infer_dtype(self, x_dtype):
  1492. validator.check_subclass("input_x", x_dtype, mstype.tensor, self.name)
  1493. return mstype.tensor_type(mstype.int32), x_dtype
  1494. class Tile(PrimitiveWithInfer):
  1495. r"""
  1496. Replicates a tensor with given multiples times.
  1497. Creates a new tensor by replicating input multiples times. The dimension of
  1498. output tensor is the larger of the input tensor dimension and the length of `multiples`.
  1499. Inputs:
  1500. - **input_x** (Tensor) - 1-D or higher Tensor. Set the shape of input tensor as
  1501. :math:`(x_1, x_2, ..., x_S)`.
  1502. - **multiples** (tuple[int]) - The input tuple is constructed by multiple
  1503. integers, i.e., :math:`(y_1, y_2, ..., y_S)`. The length of `multiples`
  1504. cannot be smaller than the length of the shape of `input_x`.
  1505. Only constant value is allowed.
  1506. Outputs:
  1507. Tensor, has the same data type as the `input_x`.
  1508. - If the length of `multiples` is the same as the length of shape of `input_x`,
  1509. then the shape of their corresponding positions can be multiplied, and
  1510. the shape of Outputs is :math:`(x_1*y_1, x_2*y_2, ..., x_S*y_R)`.
  1511. - If the length of `multiples` is larger than the length of shape of `input_x`,
  1512. fill in multiple 1 in the length of the shape of `input_x` until their lengths are consistent.
  1513. Such as set the shape of `input_x` as :math:`(1, ..., x_1, x_2, ..., x_S)`,
  1514. then the shape of their corresponding positions can be multiplied, and
  1515. the shape of Outputs is :math:`(1*y_1, ..., x_S*y_R)`.
  1516. Raises:
  1517. TypeError: If `multiples` is not a tuple or its elements are not all int.
  1518. ValueError: If the elements of `multiples` are not all greater than 0.
  1519. Supported Platforms:
  1520. ``Ascend`` ``GPU`` ``CPU``
  1521. Examples:
  1522. >>> tile = ops.Tile()
  1523. >>> input_x = Tensor(np.array([[1, 2], [3, 4]]), mindspore.float32)
  1524. >>> multiples = (2, 3)
  1525. >>> output = tile(input_x, multiples)
  1526. >>> print(output)
  1527. [[1. 2. 1. 2. 1. 2.]
  1528. [3. 4. 3. 4. 3. 4.]
  1529. [1. 2. 1. 2. 1. 2.]
  1530. [3. 4. 3. 4. 3. 4.]]
  1531. """
  1532. @prim_attr_register
  1533. def __init__(self):
  1534. """Initialize Tile"""
  1535. self.init_prim_io_names(inputs=['x', 'multiples'], outputs=['output'])
  1536. def check_elim(self, base_tensor, multiplier):
  1537. if (not isinstance(base_tensor, Tensor)) or (not isinstance(multiplier, tuple)):
  1538. raise TypeError("Expecting (Tensor, tuple), got: ({}, {})".format(base_tensor, multiplier))
  1539. if all(v == 1 for v in multiplier):
  1540. return (True, base_tensor)
  1541. return (False, None)
  1542. def __infer__(self, x, multiples):
  1543. multiples_v = multiples['value']
  1544. x_shp = x['shape']
  1545. validator.check_value_type("multiples", multiples_v, [tuple], self.name)
  1546. for i, multiple in enumerate(multiples_v):
  1547. validator.check_positive_int(multiple, "multiples[%d]" % i, self.name)
  1548. validator.check_value_type("x[\'dtype\']", x["dtype"], mstype.tensor_type, self.name)
  1549. len_sub = len(multiples_v) - len(x_shp)
  1550. multiples_w = None
  1551. if len_sub == 0:
  1552. multiples_w = multiples_v
  1553. if len_sub > 0:
  1554. for i in range(0, len_sub):
  1555. x_shp.insert(0, 1)
  1556. multiples_w = multiples_v
  1557. elif len_sub < 0:
  1558. raise ValueError(f'For \'{self.name}\' the length of multiples can not be smaller than '
  1559. f'the length of dimension in input_x.')
  1560. for i, a in enumerate(multiples_w):
  1561. x_shp[i] *= a
  1562. value = None
  1563. if x['value'] is not None:
  1564. value = Tensor(np.tile(x['value'].asnumpy(), multiples_w))
  1565. return {'shape': x_shp,
  1566. 'dtype': x['dtype'],
  1567. 'value': value}
  1568. class UnsortedSegmentSum(PrimitiveWithInfer):
  1569. r"""
  1570. Computes the sum of a tensor along segments.
  1571. Calculates a tensor such that :math:`\text{output}[i] = \sum_{segment\_ids[j] == i} \text{data}[j, \ldots]`, where
  1572. :math:`j` is a tuple describing the index of element in data. `segment_ids` selects which elements in data to sum
  1573. up. Segment_ids does not need to be sorted, and it does not need to cover all values in the entire valid value
  1574. range.
  1575. Note:
  1576. If the segment_id i is absent in the segment_ids, then output[i] will be filled with 0.
  1577. If the sum of the given segment_ids :math:`i` is empty, then :math:`\text{output}[i] = 0`. If the given segment_ids
  1578. is negative, the value will be ignored. 'num_segments' must be equal to the number of different segment_ids.
  1579. Inputs:
  1580. - **input_x** (Tensor) - The shape is :math:`(x_1, x_2, ..., x_R)`.
  1581. - **segment_ids** (Tensor) - Set the shape as :math:`(x_1, x_2, ..., x_N)`, where 0 < N <= R. Type must be int.
  1582. - **num_segments** (int) - Set :math:`z` as num_segments.
  1583. Outputs:
  1584. Tensor, the shape is :math:`(z, x_{N+1}, ..., x_R)`.
  1585. Raises:
  1586. TypeError: If `num_segments` is not an int.
  1587. ValueError: If length of shape of `segment_ids` is less than 1.
  1588. Supported Platforms:
  1589. ``Ascend`` ``GPU``
  1590. Examples:
  1591. >>> input_x = Tensor([1, 2, 3, 4], mindspore.float32)
  1592. >>> segment_ids = Tensor([0, 0, 1, 2], mindspore.int32)
  1593. >>> num_segments = 4
  1594. >>> output = ops.UnsortedSegmentSum()(input_x, segment_ids, num_segments)
  1595. >>> print(output)
  1596. [3. 3. 4. 0.]
  1597. """
  1598. @prim_attr_register
  1599. def __init__(self):
  1600. """Initialize UnsortedSegmentSum"""
  1601. self.init_prim_io_names(inputs=['x', 'segment_ids', 'num_segments'], outputs=['y'])
  1602. def __infer__(self, x, segment_ids, num_segments):
  1603. x_type = x['dtype']
  1604. x_shp = x['shape']
  1605. validator.check_subclass("input_x", x_type, mstype.tensor, self.name)
  1606. validator.check_value_type("x_shape", x_shp, [list], self.name)
  1607. x_shp_len = len(x_shp)
  1608. validator.check_positive_int(x_shp_len, "rank of input_x", self.name)
  1609. segment_ids_shp = segment_ids['shape']
  1610. segment_ids_type = segment_ids['dtype']
  1611. validator.check_subclass("segment_ids", segment_ids_type, mstype.tensor, self.name)
  1612. validator.check_value_type("segment_ids", segment_ids_shp, [list], self.name)
  1613. segment_ids_shp_len = len(segment_ids_shp)
  1614. validator.check_positive_int(segment_ids_shp_len, "rank of segment_ids", self.name)
  1615. validator.check(f'rank of input_x', len(x_shp),
  1616. 'rank of segments_id', len(segment_ids_shp), Rel.GE, self.name)
  1617. if (not -1 in x_shp and not -1 in segment_ids_shp):
  1618. # only validate when both shapes fully known
  1619. for i, value in enumerate(segment_ids_shp):
  1620. validator.check("ids[%d]" % i, value, 'input[%d]' % i, x_shp[i], Rel.EQ, self.name)
  1621. num_segments_v = num_segments['value']
  1622. num_segments_type = num_segments['dtype']
  1623. validator.check_subclass("num_segments", num_segments_type, [mstype.tensor, mstype.number], self.name)
  1624. if isinstance(num_segments_type, type(mstype.tensor)):
  1625. validator.check_tensor_dtype_valid("num_segments", num_segments_type, [mstype.int32, mstype.int64],
  1626. self.name)
  1627. shp = [-1]
  1628. else:
  1629. validator.check_value_type('num_segments', num_segments_v, [int], self.name)
  1630. validator.check_positive_int(num_segments_v, "num_segments", self.name)
  1631. shp = [num_segments_v]
  1632. shp += x_shp[segment_ids_shp_len:]
  1633. if "max_value" in num_segments and "min_value" in num_segments:
  1634. output_max_shape = list(num_segments['max_value'])
  1635. output_min_shape = list(num_segments['min_value'])
  1636. else:
  1637. if isinstance(num_segments_type, type(mstype.tensor)):
  1638. raise ValueError("Num_segments only support int type when it is not a dynamic value")
  1639. output_max_shape = [num_segments_v]
  1640. output_min_shape = [num_segments_v]
  1641. if 'max_shape' in x and 'min_shape' in x:
  1642. max_output_incoming = x['max_shape']
  1643. min_output_incoming = x['min_shape']
  1644. else:
  1645. max_output_incoming = x_shp
  1646. min_output_incoming = x_shp
  1647. output_max_shape += max_output_incoming[segment_ids_shp_len:]
  1648. output_min_shape += min_output_incoming[segment_ids_shp_len:]
  1649. return {'shape': shp,
  1650. 'max_shape': output_max_shape,
  1651. 'min_shape': output_min_shape,
  1652. 'dtype': mstype.tensor_type(x_type.element_type()),
  1653. 'value': None}
  1654. class UnsortedSegmentMin(PrimitiveWithCheck):
  1655. """
  1656. Computes the minimum of a tensor along segments.
  1657. Inputs:
  1658. - **input_x** (Tensor) - The shape is :math:`(x_1, x_2, ..., x_R)`.
  1659. The data type must be float16, float32 or int32.
  1660. - **segment_ids** (Tensor) - A `1-D` tensor whose shape is :math:`(x_1)`, the value must be >= 0.
  1661. The data type must be int32.
  1662. - **num_segments** (int) - The value specifies the number of distinct `segment_ids`.
  1663. Note:
  1664. If the segment_id i is absent in the segment_ids, then output[i] will be filled with
  1665. the maximum value of the input_x's type.
  1666. Outputs:
  1667. Tensor, set the number of `num_segments` as `N`, the shape is :math:`(N, x_2, ..., x_R)`.
  1668. Raises:
  1669. TypeError: If `num_segments` is not an int.
  1670. ValueError: If length of shape of `segment_ids` is not equal to 1.
  1671. Supported Platforms:
  1672. ``Ascend`` ``GPU``
  1673. Examples:
  1674. >>> input_x = Tensor(np.array([[1, 2, 3], [4, 5, 6], [4, 2, 1]]).astype(np.float32))
  1675. >>> segment_ids = Tensor(np.array([0, 1, 1]).astype(np.int32))
  1676. >>> num_segments = 2
  1677. >>> unsorted_segment_min = ops.UnsortedSegmentMin()
  1678. >>> output = unsorted_segment_min(input_x, segment_ids, num_segments)
  1679. >>> print(output)
  1680. [[1. 2. 3.]
  1681. [4. 2. 1.]]
  1682. """
  1683. @prim_attr_register
  1684. def __init__(self):
  1685. """Initialize UnsortedSegmentMin"""
  1686. self.init_prim_io_names(inputs=['x', 'segment_ids', 'num_segments'], outputs=['y'])
  1687. def __check__(self, x, segment_ids, num_segments):
  1688. x_shape = x['shape']
  1689. segment_ids_shape = segment_ids['shape']
  1690. valid_type = [mstype.float16, mstype.float32, mstype.int32]
  1691. validator.check_tensor_dtype_valid("x", x['dtype'], valid_type, self.name)
  1692. validator.check_tensor_dtype_valid("segment_ids", segment_ids['dtype'], [mstype.int32], self.name)
  1693. validator.check_equal_int(len(segment_ids_shape), 1, "rank of segment_ids_shape", self.name)
  1694. num_segments_type = num_segments['dtype']
  1695. validator.check_subclass("num_segments", num_segments_type, [mstype.number], self.name)
  1696. if (not -1 in x_shape and not -1 in segment_ids_shape):
  1697. # only validate when both shapes fully known
  1698. validator.check(f'first shape of input_x', x_shape[0],
  1699. 'length of segments_id', segment_ids_shape[0], Rel.EQ, self.name)
  1700. num_segments_v = num_segments['value']
  1701. validator.check_value_type('num_segments', num_segments_v, [int], self.name)
  1702. validator.check_positive_int(num_segments_v, "num_segments", self.name)
  1703. class UnsortedSegmentMax(PrimitiveWithCheck):
  1704. """
  1705. Computes the maximum along segments of a tensor.
  1706. Inputs:
  1707. - **input_x** (Tensor) - The shape is :math:`(x_1, x_2, ..., x_R)`.
  1708. The data type must be float16, float32 or int32.
  1709. - **segment_ids** (Tensor) - A `1-D` tensor whose shape is :math:`(x_1)`, the value must be >= 0.
  1710. The data type must be int32.
  1711. - **num_segments** (int) - The value specifies the number of distinct `segment_ids`.
  1712. Note:
  1713. If the segment_id i is absent in the segment_ids, then output[i] will be filled with
  1714. the minimum value of the input_x's type.
  1715. Outputs:
  1716. Tensor, set the number of `num_segments` as `N`, the shape is :math:`(N, x_2, ..., x_R)`.
  1717. Raises:
  1718. TypeError: If `num_segments` is not an int.
  1719. ValueError: If length of shape of `segment_ids` is not equal to 1.
  1720. Supported Platforms:
  1721. ``Ascend`` ``GPU``
  1722. Examples:
  1723. >>> input_x = Tensor(np.array([[1, 2, 3], [4, 5, 6], [4, 2, 1]]).astype(np.float32))
  1724. >>> segment_ids = Tensor(np.array([0, 1, 1]).astype(np.int32))
  1725. >>> num_segments = 2
  1726. >>> unsorted_segment_max = ops.UnsortedSegmentMax()
  1727. >>> output = unsorted_segment_max(input_x, segment_ids, num_segments)
  1728. >>> print(output)
  1729. [[1. 2. 3.]
  1730. [4. 5. 6.]]
  1731. """
  1732. @prim_attr_register
  1733. def __init__(self):
  1734. """Initialize UnsortedSegmentMax"""
  1735. self.init_prim_io_names(inputs=['x', 'segment_ids', 'num_segments'], outputs=['y'])
  1736. def __check__(self, x, segment_ids, num_segments):
  1737. x_shape = x['shape']
  1738. segment_ids_shape = segment_ids['shape']
  1739. valid_type = [mstype.float16, mstype.float32, mstype.int32]
  1740. validator.check_tensor_dtype_valid("x", x['dtype'], valid_type, self.name)
  1741. validator.check_tensors_dtypes_same_and_valid({"segment_ids": segment_ids['dtype']},
  1742. [mstype.int32, mstype.int64], self.name)
  1743. validator.check_equal_int(len(segment_ids_shape), 1, "rank of segment_ids_shape", self.name)
  1744. num_segments_type = num_segments['dtype']
  1745. validator.check_subclass("num_segments", num_segments_type, [mstype.number], self.name)
  1746. if (not -1 in x_shape and not -1 in segment_ids_shape):
  1747. # only validate when both shapes fully known
  1748. validator.check(f'first shape of input_x', x_shape[0],
  1749. 'length of segments_id', segment_ids_shape[0], Rel.EQ, self.name)
  1750. num_segments_v = num_segments['value']
  1751. validator.check_value_type('num_segments', num_segments_v, [int], self.name)
  1752. validator.check_positive_int(num_segments_v, "num_segments", self.name)
  1753. class UnsortedSegmentProd(PrimitiveWithInfer):
  1754. """
  1755. Computes the product of a tensor along segments.
  1756. Inputs:
  1757. - **input_x** (Tensor) - The shape is :math:`(x_1, x_2, ..., x_R)`.
  1758. With float16, float32 or int32 data type.
  1759. - **segment_ids** (Tensor) - A `1-D` tensor whose shape is :math:`(x_1)`, the value must be >= 0.
  1760. Data type must be int32.
  1761. - **num_segments** (int) - The value specifies the number of distinct `segment_ids`,
  1762. must be greater than 0.
  1763. Outputs:
  1764. Tensor, set the number of `num_segments` as `N`, the shape is :math:`(N, x_2, ..., x_R)`.
  1765. Raises:
  1766. TypeError: If `num_segments` is not an int.
  1767. ValueError: If length of shape of `segment_ids` is not equal to 1.
  1768. Supported Platforms:
  1769. ``Ascend``
  1770. Examples:
  1771. >>> input_x = Tensor(np.array([[1, 2, 3], [4, 5, 6], [4, 2, 1]]).astype(np.float32))
  1772. >>> segment_ids = Tensor(np.array([0, 1, 0]).astype(np.int32))
  1773. >>> num_segments = 2
  1774. >>> unsorted_segment_prod = ops.UnsortedSegmentProd()
  1775. >>> output = unsorted_segment_prod(input_x, segment_ids, num_segments)
  1776. >>> print(output)
  1777. [[4. 4. 3.]
  1778. [4. 5. 6.]]
  1779. """
  1780. @prim_attr_register
  1781. def __init__(self):
  1782. """Initialize UnsortedSegmentProd"""
  1783. self.init_prim_io_names(inputs=['x', 'segment_ids', 'num_segments'], outputs=['y'])
  1784. def __infer__(self, x, segment_ids, num_segments):
  1785. x_type = x['dtype']
  1786. x_shape = x['shape']
  1787. segment_ids_shape = segment_ids['shape']
  1788. validator.check_subclass("input_x", x_type, mstype.tensor, self.name)
  1789. validator.check_value_type("x_shape", x_shape, [list], self.name)
  1790. valid_type = [mstype.float16, mstype.float32, mstype.int32]
  1791. validator.check_tensor_dtype_valid("x", x['dtype'], valid_type, self.name)
  1792. validator.check_tensor_dtype_valid("segment_ids", segment_ids['dtype'], [mstype.int32], self.name)
  1793. validator.check_equal_int(len(segment_ids_shape), 1, "rank of segment_ids_shape", self.name)
  1794. validator.check(f'first shape of input_x', x_shape[0],
  1795. 'length of segments_id', segment_ids_shape[0], Rel.EQ, self.name)
  1796. num_segments_v = num_segments['value']
  1797. validator.check_value_type('num_segments', num_segments_v, [int], self.name)
  1798. validator.check_positive_int(num_segments_v, "num_segments", self.name)
  1799. segment_ids_shape_len = len(segment_ids_shape)
  1800. out_shape = [num_segments_v]
  1801. out_shape += x_shape[segment_ids_shape_len:]
  1802. out = {'shape': out_shape,
  1803. 'dtype': mstype.tensor_type(x_type.element_type()),
  1804. 'value': None}
  1805. return out
  1806. class Concat(PrimitiveWithInfer):
  1807. r"""
  1808. Connect tensor in the specified axis.
  1809. Connect input tensors along with the given axis.
  1810. The input data is a tuple of tensors. These tensors have the same rank `R`. Set the given axis as `m`, and
  1811. :math:`0 \le m < R`. Set the number of input tensors as `N`. For the :math:`i`-th tensor :math:`t_i`, it has
  1812. the shape of :math:`(x_1, x_2, ..., x_{mi}, ..., x_R)`. :math:`x_{mi}` is the :math:`m`-th dimension of the
  1813. :math:`i`-th tensor. Then, the shape of the output tensor is
  1814. .. math::
  1815. (x_1, x_2, ..., \sum_{i=1}^Nx_{mi}, ..., x_R)
  1816. Args:
  1817. axis (int): The specified axis. Default: 0.
  1818. Inputs:
  1819. - **input_x** (tuple, list) - A tuple or a list of input tensors.
  1820. Outputs:
  1821. Tensor, the shape is :math:`(x_1, x_2, ..., \sum_{i=1}^Nx_{mi}, ..., x_R)`.
  1822. Raises:
  1823. TypeError: If `axis` is not an int.
  1824. Supported Platforms:
  1825. ``Ascend`` ``GPU`` ``CPU``
  1826. Examples:
  1827. >>> data1 = Tensor(np.array([[0, 1], [2, 1]]).astype(np.float32))
  1828. >>> data2 = Tensor(np.array([[0, 1], [2, 1]]).astype(np.float32))
  1829. >>> op = ops.Concat()
  1830. >>> output = op((data1, data2))
  1831. >>> print(output)
  1832. [[0. 1.]
  1833. [2. 1.]
  1834. [0. 1.]
  1835. [2. 1.]]
  1836. """
  1837. @prim_attr_register
  1838. def __init__(self, axis=0):
  1839. """Initialize Concat"""
  1840. validator.check_value_type("axis", axis, [int], self.name)
  1841. def __infer__(self, input_x):
  1842. axis = self.axis
  1843. x_shp = input_x['shape']
  1844. x_type = input_x['dtype']
  1845. _, all_shp, _ = get_concat_offset(x_shp, x_type, axis, self.name)
  1846. self.add_prim_attr('inputNums', len(x_shp))
  1847. ret_shp = x_shp[0].copy()
  1848. value = None
  1849. if input_x['value'] is not None:
  1850. value = Tensor(np.concatenate([x.asnumpy() for x in input_x['value']], axis=axis))
  1851. ret_shp[axis] = all_shp
  1852. out = {'shape': ret_shp,
  1853. 'dtype': x_type[0],
  1854. 'value': value}
  1855. if -1 in x_shp[0]:
  1856. x_min_shp = input_x['min_shape']
  1857. ret_min_shp = x_min_shp[0].copy()
  1858. ret_min_shp[axis] = 0
  1859. for all_min_shp in x_min_shp:
  1860. ret_min_shp[axis] += all_min_shp[axis]
  1861. out['min_shape'] = ret_min_shp
  1862. x_max_shp = input_x['max_shape']
  1863. ret_max_shp = x_max_shp[0].copy()
  1864. ret_max_shp[axis] = 0
  1865. for all_max_shp in x_max_shp:
  1866. ret_max_shp[axis] += all_max_shp[axis]
  1867. out['max_shape'] = ret_max_shp
  1868. return out
  1869. class ParallelConcat(PrimitiveWithInfer):
  1870. r"""
  1871. Concats tensor in the first dimension.
  1872. Concats input tensors along with the first dimension.
  1873. Note:
  1874. The input tensors are all required to have size 1 in the first dimension.
  1875. Inputs:
  1876. - **values** (tuple, list) - A tuple or a list of input tensors. The data type and shape of these
  1877. tensors must be the same.
  1878. Outputs:
  1879. Tensor, data type is the same as `values`.
  1880. Raises:
  1881. ValueError: If length of shape of `values` is less than 1.
  1882. Supported Platforms:
  1883. ``Ascend``
  1884. Examples:
  1885. >>> data1 = Tensor(np.array([[0, 1]]).astype(np.int32))
  1886. >>> data2 = Tensor(np.array([[2, 1]]).astype(np.int32))
  1887. >>> op = ops.ParallelConcat()
  1888. >>> output = op((data1, data2))
  1889. >>> print(output)
  1890. [[0 1]
  1891. [2 1]]
  1892. """
  1893. @prim_attr_register
  1894. def __init__(self):
  1895. """Initialize ParallelConcat"""
  1896. def __infer__(self, values):
  1897. x_shp = values['shape']
  1898. x_type = values['dtype']
  1899. validator.check_int(len(x_shp), 1, Rel.GE, f'x_shp length', self.name)
  1900. args = {f"x_type[{i}]": elem for i, elem in enumerate(x_type)}
  1901. validator.check_tensors_dtypes_same_and_valid(args, mstype.number_type + (mstype.bool_,), self.name)
  1902. first_elem = x_shp[0]
  1903. for i, elem in enumerate(x_shp[1:]):
  1904. j = i + 1
  1905. validator.check_equal_int(elem[0], 1, f'x_shp[{j}][0]', self.name)
  1906. validator.check(f"x_shp[0] shape", first_elem, f"x_shp[{j}] shape", elem, Rel.EQ, self.name)
  1907. ret_shp = x_shp[0].copy()
  1908. ret_shp[0] = len(x_shp)
  1909. self.add_prim_attr('shape', ret_shp)
  1910. self.add_prim_attr('N', len(x_shp))
  1911. out = {'shape': ret_shp,
  1912. 'dtype': x_type[0],
  1913. 'value': None}
  1914. return out
  1915. def _get_stack_shape(x_shape, x_type, axis, prim_name):
  1916. """for stack output shape"""
  1917. validator.check_value_type("shape", x_shape, [tuple, list], prim_name)
  1918. validator.check_int(len(x_shape), 1, Rel.GE, "len of input_x", prim_name)
  1919. validator.check_subclass("input_x[0]", x_type[0], mstype.tensor, prim_name)
  1920. rank_base = len(x_shape[0])
  1921. N = len(x_shape)
  1922. out_shape = x_shape[0]
  1923. validator.check_int_range(axis, -rank_base - 1, rank_base, Rel.INC_BOTH, 'axis', prim_name)
  1924. if axis < 0:
  1925. axis = axis + rank_base + 1
  1926. for i in range(1, N):
  1927. validator.check('x_type[%d]' % i, x_type[i], 'base', x_type[0], Rel.EQ, prim_name, TypeError)
  1928. if x_shape[i] != x_shape[0]:
  1929. raise ValueError(f"For \'{prim_name}\' element {i} shape in input can not pack with first element")
  1930. out_shape.insert(axis, N)
  1931. return out_shape
  1932. class Pack(PrimitiveWithInfer):
  1933. """
  1934. Same as operator Stack. Pack will be deprecated in the future.
  1935. Please use Stack instead.
  1936. """
  1937. @deprecated("1.1", "Stack", True)
  1938. @prim_attr_register
  1939. def __init__(self, axis=0):
  1940. """Initialize Pack"""
  1941. validator.check_value_type("axis", axis, [int], self.name)
  1942. self.axis = axis
  1943. def __infer__(self, value):
  1944. x_shape = value['shape']
  1945. x_type = value['dtype']
  1946. self.add_prim_attr('num', len(x_shape))
  1947. all_shape = _get_stack_shape(x_shape, x_type, self.axis, self.name)
  1948. out = {'shape': all_shape,
  1949. 'dtype': x_type[0],
  1950. 'value': None}
  1951. return out
  1952. class Stack(PrimitiveWithInfer):
  1953. r"""
  1954. Stacks a list of tensors in specified axis.
  1955. Stacks the list of input tensors with the same rank `R`, output is a tensor of rank `(R+1)`.
  1956. Given input tensors of shape :math:`(x_1, x_2, ..., x_R)`. Set the number of input tensors as `N`.
  1957. If :math:`0 \le axis`, the shape of the output tensor is :math:`(x_1, x_2, ..., x_{axis}, N, x_{axis+1}, ..., x_R)`.
  1958. Args:
  1959. axis (int): Dimension to stack. Default: 0.
  1960. Negative values wrap around. The range is [-(R+1), R+1).
  1961. Inputs:
  1962. - **input_x** (Union[tuple, list]) - A Tuple or list of Tensor objects with the same shape and type.
  1963. Outputs:
  1964. Tensor. A stacked Tensor with the same type as `input_x`.
  1965. Raises:
  1966. TypeError: If the data types of elements in `input_x` are not the same.
  1967. ValueError: If the length of `input_x` is not greater than 1;
  1968. or if axis is out of the range [-(R+1), R+1);
  1969. or if the shapes of elements in input_x are not the same.
  1970. Supported Platforms:
  1971. ``Ascend`` ``GPU`` ``CPU``
  1972. Examples:
  1973. >>> data1 = Tensor(np.array([0, 1]).astype(np.float32))
  1974. >>> data2 = Tensor(np.array([2, 3]).astype(np.float32))
  1975. >>> stack = ops.Stack()
  1976. >>> output = stack([data1, data2])
  1977. >>> print(output)
  1978. [[0. 1.]
  1979. [2. 3.]]
  1980. """
  1981. @prim_attr_register
  1982. def __init__(self, axis=0):
  1983. """Initialize Stack"""
  1984. validator.check_value_type("axis", axis, [int], self.name)
  1985. self.axis = axis
  1986. def __infer__(self, value):
  1987. x_shape = value['shape']
  1988. x_type = value['dtype']
  1989. self.add_prim_attr('num', len(x_shape))
  1990. all_shape = _get_stack_shape(x_shape, x_type, self.axis, self.name)
  1991. out = {'shape': all_shape,
  1992. 'dtype': x_type[0],
  1993. 'value': None}
  1994. return out
  1995. class Unpack(PrimitiveWithInfer):
  1996. """
  1997. Same as operator Unstack. Unpack will be deprecated in the future.
  1998. Please use Unstack instead.
  1999. """
  2000. @deprecated("1.1", "Unstack", True)
  2001. @prim_attr_register
  2002. def __init__(self, axis=0):
  2003. """Initialize Unpack"""
  2004. validator.check_value_type("axis", axis, [int], self.name)
  2005. self.axis = axis
  2006. def __infer__(self, x):
  2007. validator.check_subclass("x", x['dtype'], mstype.tensor, self.name)
  2008. x_shape = list(x['shape'])
  2009. dim = len(x_shape)
  2010. validator.check_int_range(self.axis, -dim, dim, Rel.INC_LEFT, 'axis value', self.name)
  2011. if self.axis < 0:
  2012. self.axis = self.axis + dim
  2013. output_num = x_shape[self.axis]
  2014. validator.check_value_type("num", output_num, [int], self.name)
  2015. validator.check_positive_int(output_num, "output_num", self.name)
  2016. self.add_prim_attr('num', output_num)
  2017. output_valid_check = x_shape[self.axis] - output_num
  2018. validator.check_int(output_valid_check, 0, Rel.EQ,
  2019. "The dimension which to unstack divides output_num", self.name)
  2020. out_shapes = []
  2021. out_dtypes = []
  2022. out_shape = x_shape[:self.axis] + x_shape[self.axis + 1:]
  2023. for _ in range(output_num):
  2024. out_shapes.append(tuple(out_shape))
  2025. out_dtypes.append(x['dtype'])
  2026. out_shapes = tuple(out_shapes)
  2027. out_dtypes = tuple(out_dtypes)
  2028. out = {'shape': out_shapes,
  2029. 'dtype': out_dtypes,
  2030. 'value': None}
  2031. return out
  2032. class Unstack(PrimitiveWithInfer):
  2033. r"""
  2034. Unstacks tensor in specified axis.
  2035. Unstacks a tensor of rank `R` along axis dimension, output tensors will have rank `(R-1)`.
  2036. Given a tensor of shape :math:`(x_1, x_2, ..., x_R)`. If :math:`0 \le axis`,
  2037. the shape of tensor in output is :math:`(x_1, x_2, ..., x_{axis}, x_{axis+2}, ..., x_R)`.
  2038. This is the opposite of pack.
  2039. Args:
  2040. axis (int): Dimension along which to pack. Default: 0.
  2041. Negative values wrap around. The range is [-R, R).
  2042. Inputs:
  2043. - **input_x** (Tensor) - The shape is :math:`(x_1, x_2, ..., x_R)`.
  2044. A tensor to be unstacked and the rank of the tensor must be greater than 0.
  2045. Outputs:
  2046. A tuple of tensors, the shape of each objects is the same.
  2047. Raises:
  2048. ValueError: If axis is out of the range [-len(input_x.shape), len(input_x.shape)).
  2049. Supported Platforms:
  2050. ``Ascend`` ``GPU`` ``CPU``
  2051. Examples:
  2052. >>> unstack = ops.Unstack()
  2053. >>> input_x = Tensor(np.array([[1, 1, 1, 1], [2, 2, 2, 2]]))
  2054. >>> output = unstack(input_x)
  2055. >>> print(output)
  2056. (Tensor(shape=[4], dtype=Int32, value= [1, 1, 1, 1]),
  2057. Tensor(shape=[4], dtype=Int32, value= [2, 2, 2, 2]))
  2058. """
  2059. @prim_attr_register
  2060. def __init__(self, axis=0):
  2061. """Initialize Unstack"""
  2062. validator.check_value_type("axis", axis, [int], self.name)
  2063. self.axis = axis
  2064. def __infer__(self, x):
  2065. validator.check_subclass("x", x['dtype'], mstype.tensor, self.name)
  2066. x_shape = list(x['shape'])
  2067. dim = len(x_shape)
  2068. validator.check_int_range(self.axis, -dim, dim, Rel.INC_LEFT, 'axis value', self.name)
  2069. if self.axis < 0:
  2070. self.axis = self.axis + dim
  2071. output_num = x_shape[self.axis]
  2072. validator.check_value_type("num", output_num, [int], self.name)
  2073. validator.check_positive_int(output_num, "output_num", self.name)
  2074. self.add_prim_attr('num', output_num)
  2075. output_valid_check = x_shape[self.axis] - output_num
  2076. validator.check_int(output_valid_check, 0, Rel.EQ,
  2077. "The dimension which to unstack divides output_num", self.name)
  2078. out_shapes = []
  2079. out_dtypes = []
  2080. out_shape = x_shape[:self.axis] + x_shape[self.axis + 1:]
  2081. for _ in range(output_num):
  2082. out_shapes.append(tuple(out_shape))
  2083. out_dtypes.append(x['dtype'])
  2084. out_shapes = tuple(out_shapes)
  2085. out_dtypes = tuple(out_dtypes)
  2086. out = {'shape': out_shapes,
  2087. 'dtype': out_dtypes,
  2088. 'value': None}
  2089. return out
  2090. class Slice(PrimitiveWithInfer):
  2091. """
  2092. Slices a tensor in the specified shape.
  2093. Inputs:
  2094. - **x** (Tensor): The target tensor.
  2095. - **begin** (tuple, list): The beginning of the slice. Only constant value is allowed.
  2096. - **size** (tuple, list): The size of the slice. Only constant value is allowed.
  2097. Outputs:
  2098. Tensor, the shape is : input `size`, the data type is the same as input `x`.
  2099. Raises:
  2100. TypeError: If `begin` or `size` is neither tuple nor list.
  2101. Supported Platforms:
  2102. ``Ascend`` ``GPU`` ``CPU``
  2103. Examples:
  2104. >>> data = Tensor(np.array([[[1, 1, 1], [2, 2, 2]],
  2105. ... [[3, 3, 3], [4, 4, 4]],
  2106. ... [[5, 5, 5], [6, 6, 6]]]).astype(np.int32))
  2107. >>> slice = ops.Slice()
  2108. >>> output = slice(data, (1, 0, 0), (1, 1, 3))
  2109. >>> print(output)
  2110. [[[3 3 3]]]
  2111. """
  2112. @prim_attr_register
  2113. def __init__(self):
  2114. """Initialize slice"""
  2115. self.init_prim_io_names(inputs=['x', 'begin', 'size'], outputs=['output'])
  2116. def __infer__(self, x, begin, size):
  2117. x_shape = x['shape']
  2118. x_shp_len = len(x_shape)
  2119. validator.check_const_input('begin', begin['value'], self.name)
  2120. validator.check_const_input('size', size['value'], self.name)
  2121. begin_v, size_v = begin['value'], size['value']
  2122. if begin_v is None or size_v is None:
  2123. return {'shape': None,
  2124. 'dtype': x['dtype'],
  2125. 'value': None}
  2126. validator.check_value_type("input begin", begin_v, [tuple, list], self.name)
  2127. validator.check_value_type("input size", size_v, [tuple, list], self.name)
  2128. for key, value in zip(('begin', 'size'), (begin_v, size_v)):
  2129. validator.check(f'len of {key}', len(value),
  2130. 'len x\'s dim', x_shp_len)
  2131. for i in range(x_shp_len):
  2132. validator.check_positive_int(size_v[i], f'input size[{i}]')
  2133. if x_shape[i] < begin_v[i] + size_v[i]:
  2134. y = begin_v[i] + size_v[i]
  2135. raise ValueError("For '%s' slice shape can not bigger than origin shape %d, %d." %
  2136. (self.name, x_shape[i], y))
  2137. return {'shape': size_v,
  2138. 'dtype': x['dtype'],
  2139. 'value': None}
  2140. class ReverseV2(PrimitiveWithInfer):
  2141. """
  2142. Reverses specific dimensions of a tensor.
  2143. Args:
  2144. axis (Union[tuple(int), list(int)): The indices of the dimensions to reverse.
  2145. Inputs:
  2146. - **input_x** (Tensor) - The target tensor.
  2147. Outputs:
  2148. Tensor, has the same shape and type as `input_x`.
  2149. Raises:
  2150. TypeError: If `axis` is neither list nor tuple.
  2151. TypeError: If element of `axis` is not an int.
  2152. Supported Platforms:
  2153. ``Ascend``
  2154. Examples:
  2155. >>> input_x = Tensor(np.array([[1, 2, 3, 4], [5, 6, 7, 8]]), mindspore.int32)
  2156. >>> op = ops.ReverseV2(axis=[1])
  2157. >>> output = op(input_x)
  2158. >>> print(output)
  2159. [[4 3 2 1]
  2160. [8 7 6 5]]
  2161. """
  2162. @prim_attr_register
  2163. def __init__(self, axis):
  2164. validator.check_value_type('axis', axis, [list, tuple], self.name)
  2165. for i, each in enumerate(axis):
  2166. validator.check_value_type(f'axis[{i}]', each, [int], self.name)
  2167. self.axis = axis
  2168. self.init_prim_io_names(inputs=['x'], outputs=['output'])
  2169. def infer_shape(self, x_shape):
  2170. dim = len(x_shape)
  2171. for i, each in enumerate(self.axis):
  2172. validator.check_int_range(each, -dim, dim, Rel.INC_LEFT, f'axis[{i}]', self.name)
  2173. return x_shape
  2174. def infer_dtype(self, x_dtype):
  2175. validator.check_tensor_dtype_valid('x', x_dtype, (mstype.bool_,) + mstype.number_type, self.name)
  2176. return x_dtype
  2177. class Rint(PrimitiveWithInfer):
  2178. """
  2179. Returns an integer that is closest to x element-wise.
  2180. Inputs:
  2181. - **input_x** (Tensor) - The target tensor, which must be one of the following types:
  2182. float16, float32.
  2183. Outputs:
  2184. Tensor, has the same shape and type as `input_x`.
  2185. Raises:
  2186. TypeError: If dtype of `input_x` is neither float16 nor float32.
  2187. Supported Platforms:
  2188. ``Ascend``
  2189. Examples:
  2190. >>> input_x = Tensor(np.array([-1.6, -0.1, 1.5, 2.0]), mindspore.float32)
  2191. >>> op = ops.Rint()
  2192. >>> output = op(input_x)
  2193. >>> print(output)
  2194. [-2. 0. 2. 2.]
  2195. """
  2196. @prim_attr_register
  2197. def __init__(self):
  2198. self.init_prim_io_names(inputs=['x'], outputs=['output'])
  2199. def infer_shape(self, x_shape):
  2200. return x_shape
  2201. def infer_dtype(self, x_dtype):
  2202. validator.check_tensor_dtype_valid('x', x_dtype, [mstype.float16, mstype.float32], self.name)
  2203. return x_dtype
  2204. class Select(PrimitiveWithInfer):
  2205. r"""
  2206. Returns the selected elements, either from input :math:`x` or input :math:`y`, depending on the `condition`.
  2207. Given a tensor as input, this operation inserts a dimension of 1 at the dimension,
  2208. if both :math:`x` and :math:`y` are none, the operation returns the coordinates of the true
  2209. element in the `condition`, the coordinates are returned as a two-dimensional
  2210. tensor, where the first dimension (row) represents the number of true elements
  2211. and the second dimension (columns) represents the coordinates of the true
  2212. elements. Keep in mind that the shape of the output tensor can vary depending
  2213. on how many true values are in the input. Indexes are output in row-first
  2214. order.
  2215. If neither is None, :math:`x` and :math:`y` must have the same shape. If :math:`x` and :math:`y` are
  2216. scalars, the conditional tensor must be a scalar. If :math:`x` and :math:`y` are
  2217. higher-dimensional vectors, the `condition` must be a vector whose size matches the
  2218. first dimension of :math:`x`, or must have the same shape as :math:`y`.
  2219. The conditional tensor acts as an optional compensation (mask), which
  2220. determines whether the corresponding element / row in the output must be
  2221. selected from :math:`x` (if true) or :math:`y` (if false) based on the value of each
  2222. element.
  2223. If condition is a vector, then :math:`x` and :math:`y` are higher-dimensional matrices, then it
  2224. chooses to copy that row (external dimensions) from :math:`x` and :math:`y`. If condition has
  2225. the same shape as :math:`x` and :math:`y`, you can choose to copy these elements from :math:`x`
  2226. and :math:`y`.
  2227. Inputs:
  2228. - **input_cond** (Tensor[bool]) - The shape is :math:`(x_1, x_2, ..., x_N, ..., x_R)`.
  2229. The condition tensor, decides which element is chosen.
  2230. - **input_x** (Tensor) - The shape is :math:`(x_1, x_2, ..., x_N, ..., x_R)`.
  2231. The first input tensor.
  2232. - **input_y** (Tensor) - The shape is :math:`(x_1, x_2, ..., x_N, ..., x_R)`.
  2233. The second input tensor.
  2234. Outputs:
  2235. Tensor, has the same shape as `input_x`. The shape is :math:`(x_1, x_2, ..., x_N, ..., x_R)`.
  2236. Raises:
  2237. TypeError: If `input_x` or `input_y` is not a Tensor.
  2238. ValueError: If shape of `input_x` is not equal to shape of `input_y` or shape of `input_cond`.
  2239. Supported Platforms:
  2240. ``Ascend`` ``GPU`` ``CPU``
  2241. Examples:
  2242. >>> select = ops.Select()
  2243. >>> input_cond = Tensor([True, False])
  2244. >>> input_x = Tensor([2,3], mindspore.float32)
  2245. >>> input_y = Tensor([1,2], mindspore.float32)
  2246. >>> output = select(input_cond, input_x, input_y)
  2247. >>> print(output)
  2248. [2. 2.]
  2249. """
  2250. @prim_attr_register
  2251. def __init__(self):
  2252. """init"""
  2253. self.init_prim_io_names(inputs=['condition', 'x', 'y'], outputs=['output'])
  2254. def infer_shape(self, cond_shape, x_shape, y_shape):
  2255. if cond_shape != x_shape or x_shape != y_shape:
  2256. raise ValueError('The x_shape and y_shape must be the same as cond_shape.')
  2257. return x_shape
  2258. def infer_dtype(self, cond_type, x_type, y_type):
  2259. validator.check_subclass("x_type", x_type, mstype.tensor, self.name)
  2260. validator.check_subclass("y_type", y_type, mstype.tensor, self.name)
  2261. validator.check_tensor_dtype_valid("cond", cond_type, [mstype.bool_], self.name)
  2262. if x_type != y_type:
  2263. raise TypeError('\'%s\' the x_type %s must be the same as y_type %s.' % (self.name, x_type, y_type))
  2264. return x_type
  2265. def infer_value(self, cond, x, y):
  2266. if cond is not None and x is not None and y is not None:
  2267. cond = cond.asnumpy()
  2268. x = x.asnumpy()
  2269. y = y.asnumpy()
  2270. out = np.where(cond, x, y)
  2271. return Tensor(out)
  2272. return None
  2273. def _compute_slicing_length(begin, end, stride, x_shape, i):
  2274. """Computes the length of the slicing."""
  2275. if i >= len(x_shape):
  2276. raise ValueError(f"For 'StridedSlice', When their is no new axis, the index length must be less or "
  2277. f"equal than the dim of x.")
  2278. x_dim = x_shape[i]
  2279. if stride > 0:
  2280. # When slicing forward, convert begin and end to positive numbers.
  2281. if begin >= x_dim or end < -x_dim:
  2282. # When slicing forward, if begin >= x_dim or end < -x_dim, the length of the slicing is 0.
  2283. slicing_length = 0
  2284. else:
  2285. if -x_dim <= begin < 0:
  2286. begin += x_dim
  2287. if begin < -x_dim:
  2288. # When slicing forward, if begin < -x_dim, set begin = 0, which means start from the 0th element.
  2289. begin = 0
  2290. if -x_dim <= end < 0:
  2291. end += x_dim
  2292. if end > x_dim:
  2293. # When slicing forward, if end > x_dim, set end = x_dims, which means slice to the last element.
  2294. end = x_dim
  2295. if begin >= end:
  2296. # When slicing forward, if begin >= end, the length of the slicing is 0.
  2297. slicing_length = 0
  2298. else:
  2299. slicing_length = 1 + (end - 1 - begin) // stride
  2300. else:
  2301. # When slicing backward, convert begin and end to negative numbers.
  2302. if begin < -x_dim or end >= x_dim:
  2303. # When slicing backward, if begin < -x_dim or end >= x_dim, the length of the slicing is 0.
  2304. slicing_length = 0
  2305. else:
  2306. if 0 <= begin < x_dim:
  2307. begin += -x_dim
  2308. if begin >= x_dim:
  2309. begin = -1
  2310. if 0 <= end < x_dim:
  2311. end += -x_dim
  2312. if end < -x_dim - 1:
  2313. # When slicing backward, if end < -x_dim - 1, set end = -x_dim - 1, which means
  2314. # slicing to the 0th element.
  2315. end = -x_dim - 1
  2316. if begin <= end:
  2317. # When slicing backward, if begin <= end, the length of the slicing is 0.
  2318. slicing_length = 0
  2319. else:
  2320. slicing_length = 1 + (end + 1 - begin) // stride
  2321. return slicing_length
  2322. class StridedSlice(PrimitiveWithInfer):
  2323. r"""
  2324. Extracts a strided slice of a tensor.
  2325. Given an input tensor, this operation inserts a dimension of length 1 at the dimension.
  2326. This operation extracts a fragment of size (end-begin)/stride from the given 'input_tensor'.
  2327. Starting from the beginning position, the fragment continues adding stride to the index until
  2328. all dimensions are not less than the ending position.
  2329. Note:
  2330. The stride may be negative value, which causes reverse slicing.
  2331. The shape of `begin`, `end` and `strides` must be the same.
  2332. Args:
  2333. begin_mask (int): Starting index of the slice. Default: 0.
  2334. end_mask (int): Ending index of the slice. Default: 0.
  2335. ellipsis_mask (int): An int mask. Default: 0.
  2336. new_axis_mask (int): An int mask. Default: 0.
  2337. shrink_axis_mask (int): An int mask. Default: 0.
  2338. Inputs:
  2339. - **input_x** (Tensor) - The input Tensor.
  2340. - **begin** (tuple[int]) - A tuple which represents the location where to start. Only
  2341. constant value is allowed.
  2342. - **end** (tuple[int]) - A tuple or which represents the maximum location where to end.
  2343. Only constant value is allowed.
  2344. - **strides** (tuple[int]) - A tuple which represents the stride is continuously added
  2345. before reaching the maximum location. Only constant value is allowed.
  2346. Outputs:
  2347. Tensor.
  2348. The output is explained by following example.
  2349. - In the 0th dimension, begin is 1, end is 2, and strides is 1,
  2350. because :math:`1+1=2\geq2`, the interval is :math:`[1,2)`.
  2351. Thus, return the element with :math:`index = 1` in 0th dimension, i.e., [[3, 3, 3], [4, 4, 4]].
  2352. - In the 1st dimension, similarly, the interval is :math:`[0,1)`.
  2353. Based on the return value of the 0th dimension, return the element with :math:`index = 0`,
  2354. i.e., [3, 3, 3].
  2355. - In the 2nd dimension, similarly, the interval is :math:`[0,3)`.
  2356. Based on the return value of the 1st dimension, return the element with :math:`index = 0,1,2`,
  2357. i.e., [3, 3, 3].
  2358. - Finally, the output is [3, 3, 3].
  2359. Raises:
  2360. TypeError: If `begin_mask`, `end_mask`, `ellipsis_mask`, `new_axis_mask` or `shrink_axis_mask` is not an int.
  2361. TypeError: If `begin`, `end` or `strides` is not a tuple.
  2362. ValueError: If `begin_mask`, `end_mask`, `ellipsis_mask`, `new_axis_mask` or `shrink_axis_mask` is less than 0.
  2363. Supported Platforms:
  2364. ``Ascend`` ``GPU`` ``CPU``
  2365. Examples:
  2366. >>> input_x = Tensor([[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]],
  2367. ... [[5, 5, 5], [6, 6, 6]]], mindspore.float32)
  2368. >>> slice = ops.StridedSlice()
  2369. >>> output = slice(input_x, (1, 0, 0), (2, 1, 3), (1, 1, 1))
  2370. >>> print(output)
  2371. [[[3. 3. 3.]]]
  2372. """
  2373. @prim_attr_register
  2374. def __init__(self,
  2375. begin_mask=0,
  2376. end_mask=0,
  2377. ellipsis_mask=0,
  2378. new_axis_mask=0,
  2379. shrink_axis_mask=0):
  2380. """Initialize StridedSlice"""
  2381. self.init_prim_io_names(inputs=['x', 'begin', 'end', 'strides'], outputs=['output'])
  2382. validator.check_non_negative_int(begin_mask, 'begin_mask', self.name)
  2383. validator.check_non_negative_int(end_mask, 'end_mask', self.name)
  2384. validator.check_non_negative_int(ellipsis_mask, 'ellipsis_mask', self.name)
  2385. if len(tuple(filter(lambda x: x == '1', bin(ellipsis_mask)[-1:1:-1]))) > 1:
  2386. raise ValueError(f"For '{self.name}', only support one ellipsis in the index, but got {end_mask}.")
  2387. validator.check_non_negative_int(new_axis_mask, 'new_axis_mask', self.name)
  2388. validator.check_non_negative_int(shrink_axis_mask, 'shrink_axis_mask', self.name)
  2389. def __infer__(self, x, begin, end, strides):
  2390. begin_v, end_v, strides_v = begin['value'], end['value'], strides['value']
  2391. validator.check_value_type("begin", begin_v, [tuple], self.name)
  2392. validator.check_value_type("end", end_v, [tuple], self.name)
  2393. validator.check_value_type("strides", strides_v, [tuple], self.name)
  2394. if tuple(filter(lambda x: not isinstance(x, int), begin_v + end_v + strides_v)):
  2395. raise TypeError(f"For {self.name}, both the begins, ends, and strides must be a tuple of int, "
  2396. f"but got begins: {begin_v}, ends: {end_v}, strides: {strides_v}.")
  2397. if tuple(filter(lambda x: x == 0, strides_v)):
  2398. raise ValueError(f"For '{self.name}', the strides cannot contain 0, but got strides: {strides_v}.")
  2399. if len(end_v) != len(begin_v) or len(strides_v) != len(begin_v):
  2400. raise ValueError(f"For '{self.name}' the length of begin index: {begin_v}, end index: {end_v} and "
  2401. f"strides: {strides_v} must be equal.")
  2402. ret_shape = self._compute_slicing_shape(x['shape'], begin_v, end_v, strides_v)
  2403. value = None if all(ret_shape) else Tensor(np.array([]).reshape(ret_shape), x['dtype'].element_type())
  2404. if "max_value" in x and "min_value" in x:
  2405. validator.check_value_type("min_value", x["min_value"], [tuple, list], self.name)
  2406. validator.check_value_type("max_value", x["max_value"], [tuple, list], self.name)
  2407. max_value_np = np.array(x["max_value"])
  2408. min_value_np = np.array(x["min_value"])
  2409. slice_index = []
  2410. for begin_i, end_i, strides_i in zip(begin_v, end_v, strides_v):
  2411. s = slice(begin_i, end_i, strides_i)
  2412. slice_index.append(s)
  2413. slice_index = tuple(slice_index)
  2414. max_value_slice = max_value_np[slice_index]
  2415. min_value_slice = min_value_np[slice_index]
  2416. max_value_slice = tuple(max_value_slice.tolist())
  2417. min_value_slice = tuple(min_value_slice.tolist())
  2418. return {'shape': ret_shape,
  2419. 'dtype': x['dtype'],
  2420. 'value': value,
  2421. 'max_value': max_value_slice,
  2422. 'min_value': min_value_slice}
  2423. return {'shape': ret_shape,
  2424. 'dtype': x['dtype'],
  2425. 'value': value}
  2426. def _compute_slicing_shape(self, x_shape, begin_v, end_v, strides_v):
  2427. """Computes the shape of the slicing."""
  2428. x_rank = len(x_shape)
  2429. slice_len = len(begin_v)
  2430. # After the integer is converted to binary, it is a str and the first two chars are the flag char '0b'.
  2431. begin_pos = bin(self.begin_mask)[-1:1:-1]
  2432. end_pos = bin(self.end_mask)[-1:1:-1]
  2433. ellipsis_pos = bin(self.ellipsis_mask)[-1:1:-1]
  2434. new_axis_pos = bin(self.new_axis_mask)[-1:1:-1]
  2435. shrink_axis_pos = bin(self.shrink_axis_mask)[-1:1:-1]
  2436. ret_shape = []
  2437. i, j = 0, 0
  2438. has_ellipsis = False
  2439. while i < x_rank or j < slice_len:
  2440. if j < slice_len:
  2441. begin, end, stride = begin_v[j], end_v[j], strides_v[j]
  2442. if j < len(ellipsis_pos) and ellipsis_pos[j] == '1':
  2443. # When there is ellipsis, the latter part of the ellipsis will be processed separately.
  2444. has_ellipsis = True
  2445. break
  2446. if j < len(begin_pos) and begin_pos[j] == '1':
  2447. begin = -1 if strides_v[j] < 0 else 0
  2448. if j < len(end_pos) and end_pos[j] == '1':
  2449. end = -(x_shape[i] + 1) if strides_v[j] < 0 else x_shape[i]
  2450. if j < len(new_axis_pos) and new_axis_pos[j] == '1':
  2451. ret_shape.append(1)
  2452. j += 1
  2453. continue
  2454. if j < len(shrink_axis_pos) and shrink_axis_pos[j] == '1':
  2455. if (not -x_shape[i] <= begin < x_shape[i]) or stride < 0:
  2456. raise IndexError(f"For {self.name}, when shrink axis, the stride cannot be negative number, "
  2457. f"and begin should be in [-{x_shape[i]}, {x_shape[i]}), "
  2458. f"but got stride: {stride}, begin: {begin}.")
  2459. j += 1
  2460. i += 1
  2461. continue
  2462. else:
  2463. begin, end, stride = 0, x_shape[i], 1
  2464. slicing_length = _compute_slicing_length(begin, end, stride, x_shape, i)
  2465. ret_shape.append(slicing_length)
  2466. i += 1
  2467. j += 1
  2468. if has_ellipsis:
  2469. # When there is ellipsis, handle the second half of the ellipsis split.
  2470. ellipsis_occupied_dims = x_rank - i - (slice_len - (j + 1)) + \
  2471. len(tuple(filter(lambda x: x == '1', new_axis_pos[j + 1:slice_len])))
  2472. ret_shape.extend(x_shape[i:i + ellipsis_occupied_dims])
  2473. j += 1
  2474. i += ellipsis_occupied_dims
  2475. while i < x_rank or j < slice_len:
  2476. begin, end, stride = begin_v[j], end_v[j], strides_v[j]
  2477. if j < len(begin_pos) and begin_pos[j] == '1':
  2478. begin = -1 if strides_v[j] < 0 else 0
  2479. if j < len(end_pos) and end_pos[j] == '1':
  2480. end = -(x_shape[i] + 1) if strides_v[j] < 0 else x_shape[i]
  2481. if j < len(new_axis_pos) and new_axis_pos[j] == '1':
  2482. ret_shape.append(1)
  2483. j += 1
  2484. continue
  2485. if j < len(shrink_axis_pos) and shrink_axis_pos[j] == '1':
  2486. if (not -x_shape[i] <= begin < x_shape[i]) or stride < 0:
  2487. raise ValueError(f"For {self.name}, when shrink axis, the stride cannot be negative number, "
  2488. f"and begin should be in [-{x_shape[i]}, {x_shape[i]}), "
  2489. f"but got stride: {stride}, begin: {begin}.")
  2490. j += 1
  2491. i += 1
  2492. continue
  2493. slicing_length = _compute_slicing_length(begin, end, stride, x_shape, i)
  2494. ret_shape.append(slicing_length)
  2495. i += 1
  2496. j += 1
  2497. return ret_shape
  2498. class Diag(PrimitiveWithInfer):
  2499. r"""
  2500. Constructs a diagonal tensor with a given diagonal values.
  2501. Assume `input_x` has dimensions :math:`[D_1,... D_k]`, the output is a tensor of
  2502. rank 2k with dimensions :math:`[D_1,..., D_k, D_1,..., D_k]` where:
  2503. :math:`output[i_1,..., i_k, i_1,..., i_k] = input_x[i_1,..., i_k]` and 0 everywhere else.
  2504. Inputs:
  2505. - **input_x** (Tensor) - The input tensor. The input shape must be less than 5d.
  2506. Outputs:
  2507. Tensor, has the same dtype as the `input_x`.
  2508. Examples:
  2509. >>> input_x = Tensor([1, 2, 3, 4])
  2510. >>> diag = ops.Diag()
  2511. >>> output = diag(input_x)
  2512. >>> print(output)
  2513. [[1, 0, 0, 0],
  2514. [0, 2, 0, 0],
  2515. [0, 0, 3, 0],
  2516. [0, 0, 0, 4]]
  2517. """
  2518. @prim_attr_register
  2519. def __init__(self):
  2520. """Initialize Diag"""
  2521. def infer_dtype(self, x_type):
  2522. validator.check_subclass('input_x', x_type, mstype.tensor, self.name)
  2523. return x_type
  2524. def infer_shape(self, x_shape):
  2525. validator.check("x rank", len(x_shape), "", 1, Rel.GE)
  2526. ret_shape = copy.deepcopy(x_shape)
  2527. ret_shape = ret_shape + ret_shape
  2528. return ret_shape
  2529. def infer_value(self, x):
  2530. if x is None:
  2531. return None
  2532. # do constant-folding only when x rank is 1
  2533. if len(x.shape) != 1:
  2534. return None
  2535. ret = np.diag(x.asnumpy())
  2536. return Tensor(ret)
  2537. class DiagPart(PrimitiveWithInfer):
  2538. r"""
  2539. Extracts the diagonal part from given tensor.
  2540. Assume input has dimensions :math:`[D_1,..., D_k, D_1,..., D_k]`, the output is a tensor
  2541. of rank k with dimensions :math:`[D_1,..., D_k]` where:
  2542. :math:`output[i_1,..., i_k] = input[i_1,..., i_k, i_1,..., i_k]`.
  2543. Inputs:
  2544. - **input_x** (Tensor) - tensor of rank k where k is even and not zero.
  2545. Outputs:
  2546. Tensor, the extracted diagonal has the same dtype as the `input_x`.
  2547. Examples
  2548. >>> input_x = Tensor([[1, 0, 0, 0],
  2549. ... [0, 2, 0, 0],
  2550. ... [0, 0, 3, 0],
  2551. ... [0, 0, 0, 4]])
  2552. >>> diag_part = ops.DiagPart()
  2553. >>> output = diag_part(input_x)
  2554. >>> print(output)
  2555. [1 2 3 4]
  2556. """
  2557. @prim_attr_register
  2558. def __init__(self):
  2559. """Initialize DiagPart"""
  2560. def infer_dtype(self, x_type):
  2561. validator.check_subclass('input_x', x_type, mstype.tensor, self.name)
  2562. return x_type
  2563. def infer_shape(self, x_shape):
  2564. if len(x_shape) % 2 != 0 or \
  2565. not x_shape:
  2566. raise ValueError(f"For \'{self.name}\' input rank must be non-zero and even, but got rank {len(x_shape)}, "
  2567. f"with shapes {x_shape}")
  2568. length = len(x_shape) // 2
  2569. for i in range(length):
  2570. validator.check('input_shape[i + len(input_shape)/2]', x_shape[i + length],
  2571. 'input_shape[i]', x_shape[i], Rel.EQ, self.name)
  2572. ret_shape = x_shape[0:length]
  2573. return ret_shape
  2574. def infer_value(self, x):
  2575. if x is None:
  2576. return None
  2577. # do constant-folding only when x rank is 2
  2578. if len(x.shape) != 2:
  2579. return None
  2580. ret = np.diag(x.asnumpy())
  2581. return Tensor(ret)
  2582. class Eye(PrimitiveWithInfer):
  2583. """
  2584. Creates a tensor with ones on the diagonal and zeros the rest.
  2585. Inputs:
  2586. - **n** (int) - The number of rows of returned tensor
  2587. - **m** (int) - The number of columns of returned tensor
  2588. - **t** (mindspore.dtype) - MindSpore's dtype, The data type of the returned tensor.
  2589. Outputs:
  2590. Tensor, a tensor with ones on the diagonal and the rest of elements are zero.
  2591. Raises:
  2592. TypeError: If `m` or `n` is not an int.
  2593. ValueError: If `m` or `n` is less than 1.
  2594. Supported Platforms:
  2595. ``Ascend`` ``GPU`` ``CPU``
  2596. Examples:
  2597. >>> eye = ops.Eye()
  2598. >>> output = eye(2, 2, mindspore.int32)
  2599. >>> print(output)
  2600. [[1 0]
  2601. [0 1]]
  2602. """
  2603. @prim_attr_register
  2604. def __init__(self):
  2605. """Initialize Eye"""
  2606. def infer_value(self, n, m, t):
  2607. validator.check_positive_int(n, "n", self.name)
  2608. validator.check_positive_int(m, "m", self.name)
  2609. args = {"dtype": t}
  2610. validator.check_types_same_and_valid(args, mstype.number_type + (mstype.bool_,), self.name)
  2611. np_type = mstype.dtype_to_nptype(t)
  2612. ret = np.eye(n, m, dtype=np_type)
  2613. return Tensor(ret)
  2614. class ScatterNd(PrimitiveWithInfer):
  2615. r"""
  2616. Scatters a tensor into a new tensor depending on the specified indices.
  2617. Creates an empty tensor with the given `shape`, and set values by scattering the update tensor depending on indices.
  2618. The empty tensor has rank P and `indices` has rank Q where `Q >= 2`.
  2619. `indices` has shape :math:`(i_0, i_1, ..., i_{Q-2}, N)` where `N <= P`.
  2620. The last dimension of `indices` (with length `N` ) indicates slices along the `N` th dimension of the empty tensor.
  2621. `updates` is a tensor of rank `Q-1+P-N`. Its shape is: :math:`(i_0, i_1, ..., i_{Q-2}, shape_N, ..., shape_{P-1})`.
  2622. Inputs:
  2623. - **indices** (Tensor) - The index of scattering in the new tensor with int32 data type.
  2624. The rank of indices must be at least 2 and `indices_shape[-1] <= len(shape)`.
  2625. - **updates** (Tensor) - The source Tensor to be scattered.
  2626. It has shape `indices_shape[:-1] + shape[indices_shape[-1]:]`.
  2627. - **shape** (tuple[int]) - Define the shape of the output tensor, has the same type as indices.
  2628. Outputs:
  2629. Tensor, the new tensor, has the same type as `update` and the same shape as `shape`.
  2630. Raises:
  2631. TypeError: If `shape` is not a tuple.
  2632. ValueError: If any element of `shape` is less than 1.
  2633. Supported Platforms:
  2634. ``Ascend`` ``GPU``
  2635. Examples:
  2636. >>> op = ops.ScatterNd()
  2637. >>> indices = Tensor(np.array([[0, 1], [1, 1]]), mindspore.int32)
  2638. >>> updates = Tensor(np.array([3.2, 1.1]), mindspore.float32)
  2639. >>> shape = (3, 3)
  2640. >>> output = op(indices, updates, shape)
  2641. >>> print(output)
  2642. [[0. 3.2 0. ]
  2643. [0. 1.1 0. ]
  2644. [0. 0. 0. ]]
  2645. """
  2646. @prim_attr_register
  2647. def __init__(self):
  2648. """Initialize ScatterNd"""
  2649. self.init_prim_io_names(inputs=['indices', 'update', 'shape'], outputs=['output'])
  2650. def __infer__(self, indices, update, shape):
  2651. shp = shape['value']
  2652. validator.check_subclass("update_dtype", update['dtype'], mstype.tensor, self.name)
  2653. validator.check_tensor_dtype_valid("indices", indices['dtype'], [mstype.int32, mstype.int64], self.name)
  2654. validator.check_value_type("shape", shp, [tuple], self.name)
  2655. for i, x in enumerate(shp):
  2656. validator.check_positive_int(x, f'shape[{i}]', self.name)
  2657. indices_shape, update_shape = indices["shape"], update["shape"]
  2658. if indices_shape[0] != update_shape[0]:
  2659. raise ValueError(f'For \'{self.name}\' The indices_shape[0] and update_shape[0] must be equal.')
  2660. return {'shape': shp,
  2661. 'dtype': update['dtype'],
  2662. 'value': None}
  2663. class ResizeNearestNeighbor(PrimitiveWithInfer):
  2664. r"""
  2665. Resizes the input tensor by using the nearest neighbor algorithm.
  2666. Resizes the input tensor to a given size by using the nearest neighbor algorithm. The nearest
  2667. neighbor algorithm selects the value of the nearest point and does not consider the
  2668. values of neighboring points at all, yielding a piecewise-constant interpolant.
  2669. Args:
  2670. size (Union[tuple, list]): The target size. The dimension of size must be 2.
  2671. align_corners (bool): Whether the centers of the 4 corner pixels of the input
  2672. and output tensors are aligned. Default: False.
  2673. Inputs:
  2674. - **input_x** (Tensor) - The input tensor. The shape of the tensor is :math:`(N, C, H, W)`.
  2675. Outputs:
  2676. Tensor, the shape of the output tensor is :math:`(N, C, NEW\_H, NEW\_W)`.
  2677. Raises:
  2678. TypeError: If `size` is neither tuple nor list.
  2679. TypeError: If `align_corners` is not a bool.
  2680. ValueError: If length of `size` is not equal to 2.
  2681. Supported Platforms:
  2682. ``Ascend`` ``GPU`` ``CPU``
  2683. Examples:
  2684. >>> input_tensor = Tensor(np.array([[[[-0.1, 0.3, 3.6], [0.4, 0.5, -3.2]]]]), mindspore.float32)
  2685. >>> resize = ops.ResizeNearestNeighbor((2, 2))
  2686. >>> output = resize(input_tensor)
  2687. >>> print(output)
  2688. [[[[-0.1 0.3]
  2689. [ 0.4 0.5]]]]
  2690. """
  2691. @prim_attr_register
  2692. def __init__(self, size, align_corners=False):
  2693. """Initialize ResizeNearestNeighbor"""
  2694. validator.check_value_type("size", size, [tuple, list], self.name)
  2695. validator.check_value_type("align_corners", align_corners, [bool], self.name)
  2696. validator.check_equal_int(len(size), 2, "length of size", self.name)
  2697. for i, value in enumerate(size):
  2698. validator.check_non_negative_int(value, f'{i}th value of size', self.name)
  2699. self.init_prim_io_names(inputs=['image_in'], outputs=['image_out'])
  2700. def infer_shape(self, x_shape):
  2701. validator.check('the dimension of input_x', len(x_shape), '', 4, Rel.EQ, self.name)
  2702. return tuple(x_shape)[:-2] + tuple(self.size)
  2703. def infer_dtype(self, x_dtype):
  2704. validator.check_tensor_dtype_valid("x", x_dtype, mstype.number_type, self.name)
  2705. return x_dtype
  2706. class GatherNd(PrimitiveWithInfer):
  2707. """
  2708. Gathers slices from a tensor by indices.
  2709. Using given indices to gather slices from a tensor with a specified shape.
  2710. Inputs:
  2711. - **input_x** (Tensor) - The target tensor to gather values.
  2712. - **indices** (Tensor) - The index tensor, with int data type.
  2713. Outputs:
  2714. Tensor, has the same type as `input_x` and the shape is indices_shape[:-1] + x_shape[indices_shape[-1]:].
  2715. Raises:
  2716. ValueError: If length of shape of `input_x` is less than the last dimension of `indices`.
  2717. Supported Platforms:
  2718. ``Ascend`` ``GPU`` ``CPU``
  2719. Examples:
  2720. >>> input_x = Tensor(np.array([[-0.1, 0.3, 3.6], [0.4, 0.5, -3.2]]), mindspore.float32)
  2721. >>> indices = Tensor(np.array([[0, 0], [1, 1]]), mindspore.int32)
  2722. >>> op = ops.GatherNd()
  2723. >>> output = op(input_x, indices)
  2724. >>> print(output)
  2725. [-0.1 0.5]
  2726. """
  2727. @prim_attr_register
  2728. def __init__(self):
  2729. """Initialize GatherNd"""
  2730. self.init_prim_io_names(inputs=['input_x', 'indices'], outputs=['y'])
  2731. def infer_shape(self, x_shape, indices_shape):
  2732. validator.check('the dimension of x', len(x_shape),
  2733. 'the dimension of indices', indices_shape[-1], Rel.GE, self.name)
  2734. return indices_shape[:-1] + x_shape[indices_shape[-1]:]
  2735. def infer_dtype(self, x_dtype, indices_dtype):
  2736. validator.check_tensor_dtype_valid("indices", indices_dtype, mstype.int_type, self.name)
  2737. return x_dtype
  2738. class TensorScatterUpdate(PrimitiveWithInfer):
  2739. """
  2740. Creates a new tensor by updating the positions in `input_x` indicicated by
  2741. `indices`, with values from `update`. This operation is almost equivalent to using
  2742. ScatterNd, except that the updates are applied on `input_x` instead of a zero tensor.
  2743. `indices` must have rank at least 2, the last axis is the depth of each index
  2744. vectors. For each index vector, there must be a corresponding value in `update`. If
  2745. the depth of each index tensor matches the rank of `input_x`, then each index
  2746. vector corresponds to a scalar in `input_x` and each update updates a scalar. If
  2747. the depth of each index tensor is less than the rnak of `input_x`, then each index
  2748. vector corresponds to a slice in `input_x`, and each update updates a slice.
  2749. The order in which updates are applied is nondeterministic, meaning that if there
  2750. are multiple index vectors in `indices` that correspond to the same position, the
  2751. value of that position in the output will be nondeterministic.
  2752. Inputs:
  2753. - **input_x** (Tensor) - The target tensor. The dimension of input_x must be no less than indices.shape[-1].
  2754. - **indices** (Tensor) - The index of input tensor whose data type is int32 or int64.
  2755. The rank must be at least 2.
  2756. - **update** (Tensor) - The tensor to update the input tensor, has the same type as input,
  2757. and update.shape = indices.shape[:-1] + input_x.shape[indices.shape[-1]:].
  2758. Outputs:
  2759. Tensor, has the same shape and type as `input_x`.
  2760. Raises:
  2761. TypeError: If dtype of `indices` is neither int32 nor int64.
  2762. ValueError: If length of shape of `input_x` is less than the last dimension of shape of `indices`.
  2763. Supported Platforms:
  2764. ``Ascend`` ``GPU``
  2765. Examples:
  2766. >>> input_x = Tensor(np.array([[-0.1, 0.3, 3.6], [0.4, 0.5, -3.2]]), mindspore.float32)
  2767. >>> indices = Tensor(np.array([[0, 0], [1, 1]]), mindspore.int32)
  2768. >>> update = Tensor(np.array([1.0, 2.2]), mindspore.float32)
  2769. >>> op = ops.TensorScatterUpdate()
  2770. >>> output = op(input_x, indices, update)
  2771. >>> print(output)
  2772. [[ 1. 0.3 3.6]
  2773. [ 0.4 2.2 -3.2]]
  2774. """
  2775. @prim_attr_register
  2776. def __init__(self):
  2777. """Initialize TensorScatterUpdate"""
  2778. self.init_prim_io_names(inputs=['x', 'indices', 'value'], outputs=['y'])
  2779. def infer_shape(self, x_shape, indices_shape, value_shape):
  2780. validator.check('the dimension of x', len(x_shape),
  2781. 'the dimension of indices', indices_shape[-1], Rel.GE)
  2782. if indices_shape[:-1] + x_shape[indices_shape[-1]:] != value_shape:
  2783. raise ValueError("For 'TensorScatterUpdate', input value are not match with input indices.")
  2784. return x_shape
  2785. def infer_dtype(self, x_dtype, indices_dtype, value_dtype):
  2786. validator.check_tensor_dtype_valid('indices', indices_dtype, [mstype.int32, mstype.int64], self.name)
  2787. args = {"x": x_dtype, "value": value_dtype}
  2788. validator.check_tensors_dtypes_same_and_valid(args, (mstype.bool_,) + mstype.number_type, self.name)
  2789. return x_dtype
  2790. class ScatterUpdate(_ScatterOp_Dynamic):
  2791. r"""
  2792. Updates tensor values by using input indices and value.
  2793. Using given values to update tensor value, along with the input indices.
  2794. for each `i, ..., j` in `indices.shape`:
  2795. .. math::
  2796. \text{input_x}[\text{indices}[i, ..., j], :] = \text{updates}[i, ..., j, :]
  2797. Inputs of `input_x` and `updates` comply with the implicit type conversion rules to make the data types consistent.
  2798. If they have different data types, lower priority data type will be converted to
  2799. relatively highest priority data type.
  2800. RuntimeError exception will be thrown when the data type conversion of Parameter is required.
  2801. Args:
  2802. use_locking (bool): Whether protect the assignment by a lock. Default: True.
  2803. Inputs:
  2804. - **input_x** (Parameter) - The target tensor, with data type of Parameter.
  2805. - **indices** (Tensor) - The index of input tensor. With int32 data type.
  2806. If there are duplicates in indices, the order for updating is undefined.
  2807. - **updates** (Tensor) - The tensor to update the input tensor, has the same type as input,
  2808. and updates.shape = indices.shape + input_x.shape[1:].
  2809. Outputs:
  2810. Tensor, has the same shape and type as `input_x`.
  2811. Raises:
  2812. TypeError: If `use_locking` is not a bool.
  2813. Supported Platforms:
  2814. ``Ascend`` ``GPU``
  2815. Examples:
  2816. >>> np_x = np.array([[-0.1, 0.3, 3.6], [0.4, 0.5, -3.2]])
  2817. >>> input_x = mindspore.Parameter(Tensor(np_x, mindspore.float32), name="x")
  2818. >>> indices = Tensor(np.array([0, 1]), mindspore.int32)
  2819. >>> np_updates = np.array([[2.0, 1.2, 1.0], [3.0, 1.2, 1.0]])
  2820. >>> updates = Tensor(np_updates, mindspore.float32)
  2821. >>> op = ops.ScatterUpdate()
  2822. >>> output = op(input_x, indices, updates)
  2823. >>> print(output)
  2824. [[2. 1.2 1. ]
  2825. [3. 1.2 1. ]]
  2826. """
  2827. @prim_attr_register
  2828. def __init__(self, use_locking=True):
  2829. """Initialize ScatterUpdate"""
  2830. validator.check_value_type('use_locking', use_locking, [bool], self.name)
  2831. self.init_prim_io_names(inputs=['x', 'indices', 'updates'], outputs=['y'])
  2832. self.add_prim_attr('side_effect_mem', True)
  2833. class ScatterNdUpdate(_ScatterNdOp):
  2834. r"""
  2835. Updates tensor values by using input indices and value.
  2836. Using given values to update tensor value, along with the input indices.
  2837. `input_x` has rank P and `indices` has rank Q where `Q >= 2`.
  2838. `indices` has shape :math:`(i_0, i_1, ..., i_{Q-2}, N)` where `N <= P`.
  2839. The last dimension of `indices` (with length `N` ) indicates slices along the `N` th dimension of `input_x`.
  2840. `updates` is a tensor of rank `Q-1+P-N`. Its shape is:
  2841. :math:`(i_0, i_1, ..., i_{Q-2}, x\_shape_N, ..., x\_shape_{P-1})`.
  2842. Inputs of `input_x` and `updates` comply with the implicit type conversion rules to make the data types consistent.
  2843. If they have different data types, lower priority data type will be converted to
  2844. relatively highest priority data type.
  2845. RuntimeError exception will be thrown when the data type conversion of Parameter is required.
  2846. Args:
  2847. use_locking (bool): Whether protect the assignment by a lock. Default: True.
  2848. Inputs:
  2849. - **input_x** (Parameter) - The target tensor, with data type of Parameter.
  2850. - **indices** (Tensor) - The index of input tensor, with int32 data type.
  2851. The rank of indices must be at least 2 and `indices_shape[-1] <= len(shape)`.
  2852. - **updates** (Tensor) - The tensor to be updated to the input tensor, has the same type as input.
  2853. The shape is `indices_shape[:-1] + x_shape[indices_shape[-1]:]`.
  2854. Outputs:
  2855. Tensor, has the same shape and type as `input_x`.
  2856. Raises:
  2857. TypeError: If `use_locking` is not a bool.
  2858. Supported Platforms:
  2859. ``Ascend`` ``CPU``
  2860. Examples:
  2861. >>> np_x = np.array([[-0.1, 0.3, 3.6], [0.4, 0.5, -3.2]])
  2862. >>> input_x = mindspore.Parameter(Tensor(np_x, mindspore.float32), name="x")
  2863. >>> indices = Tensor(np.array([[0, 0], [1, 1]]), mindspore.int32)
  2864. >>> updates = Tensor(np.array([1.0, 2.2]), mindspore.float32)
  2865. >>> op = ops.ScatterNdUpdate()
  2866. >>> output = op(input_x, indices, updates)
  2867. >>> print(output)
  2868. [[ 1. 0.3 3.6]
  2869. [ 0.4 2.2 -3.2]]
  2870. """
  2871. @prim_attr_register
  2872. def __init__(self, use_locking=True):
  2873. """Initialize ScatterNdUpdate"""
  2874. validator.check_value_type('use_locking', use_locking, [bool], self.name)
  2875. self.init_prim_io_names(inputs=['x', 'indices', 'value'], outputs=['y'])
  2876. self.add_prim_attr('side_effect_mem', True)
  2877. def infer_dtype(self, x_dtype, indices_dtype, value_dtype):
  2878. validator.check_tensor_dtype_valid('indices', indices_dtype, [mstype.int32], self.name)
  2879. args = {"x": x_dtype, "value": value_dtype}
  2880. validator.check_tensors_dtypes_same_and_valid(args, (mstype.bool_,) + mstype.number_type, self.name)
  2881. return x_dtype
  2882. class ScatterMax(_ScatterOp):
  2883. r"""
  2884. Updates the value of the input tensor through the maximum operation.
  2885. Using given values to update tensor value through the max operation, along with the input indices.
  2886. This operation outputs the `input_x` after the update is done, which makes it convenient to use the updated value.
  2887. for each `i, ..., j` in `indices.shape`:
  2888. .. math::
  2889. \text{input_x}[\text{indices}[i, ..., j], :]
  2890. = max(\text{input_x}[\text{indices}[i, ..., j], :], \text{updates}[i, ..., j, :])
  2891. Inputs of `input_x` and `updates` comply with the implicit type conversion rules to make the data types consistent.
  2892. If they have different data types, lower priority data type will be converted to
  2893. relatively highest priority data type.
  2894. RuntimeError exception will be thrown when the data type conversion of Parameter is required.
  2895. Args:
  2896. use_locking (bool): Whether protect the assignment by a lock. Default: True.
  2897. Inputs:
  2898. - **input_x** (Parameter) - The target parameter.
  2899. - **indices** (Tensor) - The index to do max operation whose data type must be mindspore.int32.
  2900. - **updates** (Tensor) - The tensor that performs the maximum operation with `input_x`,
  2901. the data type is the same as `input_x`, the shape is `indices_shape + x_shape[1:]`.
  2902. Outputs:
  2903. Parameter, the updated `input_x`.
  2904. Raises:
  2905. TypeError: If `use_locking` is not a bool.
  2906. Supported Platforms:
  2907. ``Ascend``
  2908. Examples:
  2909. >>> input_x = Parameter(Tensor(np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]), mindspore.float32), name="input_x")
  2910. >>> indices = Tensor(np.array([[0, 0], [1, 1]]), mindspore.int32)
  2911. >>> updates = Tensor(np.ones([2, 2, 3]) * 88, mindspore.float32)
  2912. >>> scatter_max = ops.ScatterMax()
  2913. >>> output = scatter_max(input_x, indices, updates)
  2914. >>> print(output)
  2915. [[88. 88. 88.]
  2916. [88. 88. 88.]]
  2917. """
  2918. class ScatterMin(_ScatterOp):
  2919. r"""
  2920. Updates the value of the input tensor through the minimum operation.
  2921. Using given values to update tensor value through the min operation, along with the input indices.
  2922. This operation outputs the `input_x` after the update is done, which makes it convenient to use the updated value.
  2923. for each `i, ..., j` in `indices.shape`:
  2924. .. math::
  2925. \text{input_x}[\text{indices}[i, ..., j], :]
  2926. = min(\text{input_x}[\text{indices}[i, ..., j], :], \text{updates}[i, ..., j, :])
  2927. Inputs of `input_x` and `updates` comply with the implicit type conversion rules to make the data types consistent.
  2928. If they have different data types, lower priority data type will be converted to
  2929. relatively highest priority data type.
  2930. RuntimeError exception will be thrown when the data type conversion of Parameter is required.
  2931. Args:
  2932. use_locking (bool): Whether protect the assignment by a lock. Default: False.
  2933. Inputs:
  2934. - **input_x** (Parameter) - The target parameter.
  2935. - **indices** (Tensor) - The index to do min operation whose data type must be mindspore.int32.
  2936. - **updates** (Tensor) - The tensor doing the min operation with `input_x`,
  2937. the data type is same as `input_x`, the shape is `indices_shape + x_shape[1:]`.
  2938. Outputs:
  2939. Parameter, the updated `input_x`.
  2940. Raises:
  2941. TypeError: If `use_locking` is not a bool.
  2942. Supported Platforms:
  2943. ``Ascend``
  2944. Examples:
  2945. >>> input_x = Parameter(Tensor(np.array([[0.0, 1.0, 2.0], [0.0, 0.0, 0.0]]), mindspore.float32), name="input_x")
  2946. >>> indices = Tensor(np.array([[0, 0], [1, 1]]), mindspore.int32)
  2947. >>> update = Tensor(np.ones([2, 2, 3]), mindspore.float32)
  2948. >>> scatter_min = ops.ScatterMin()
  2949. >>> output = scatter_min(input_x, indices, update)
  2950. >>> print(output)
  2951. [[0. 1. 1.]
  2952. [0. 0. 0.]]
  2953. """
  2954. class ScatterAdd(_ScatterOp_Dynamic):
  2955. r"""
  2956. Updates the value of the input tensor through the addition operation.
  2957. Using given values to update tensor value through the add operation, along with the input indices.
  2958. This operation outputs the `input_x` after the update is done, which makes it convenient to use the updated value.
  2959. for each `i, ..., j` in `indices.shape`:
  2960. .. math::
  2961. \text{input_x}[\text{indices}[i, ..., j], :] \mathrel{+}= \text{updates}[i, ..., j, :]
  2962. Inputs of `input_x` and `updates` comply with the implicit type conversion rules to make the data types consistent.
  2963. If they have different data types, lower priority data type will be converted to
  2964. relatively highest priority data type.
  2965. RuntimeError exception will be thrown when the data type conversion of Parameter is required.
  2966. Args:
  2967. use_locking (bool): Whether protect the assignment by a lock. Default: False.
  2968. Inputs:
  2969. - **input_x** (Parameter) - The target parameter.
  2970. - **indices** (Tensor) - The index to do add operation whose data type must be mindspore.int32.
  2971. - **updates** (Tensor) - The tensor that performs the add operation with `input_x`,
  2972. the data type is the same as `input_x`, the shape is `indices_shape + x_shape[1:]`.
  2973. Outputs:
  2974. Parameter, the updated `input_x`.
  2975. Raises:
  2976. TypeError: If `use_locking` is not a bool.
  2977. Supported Platforms:
  2978. ``Ascend`` ``GPU``
  2979. Examples:
  2980. >>> input_x = Parameter(Tensor(np.array([[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]), mindspore.float32), name="x")
  2981. >>> indices = Tensor(np.array([[0, 1], [1, 1]]), mindspore.int32)
  2982. >>> updates = Tensor(np.ones([2, 2, 3]), mindspore.float32)
  2983. >>> scatter_add = ops.ScatterAdd()
  2984. >>> output = scatter_add(input_x, indices, updates)
  2985. >>> print(output)
  2986. [[1. 1. 1.]
  2987. [3. 3. 3.]]
  2988. """
  2989. @prim_attr_register
  2990. def __init__(self, use_locking=False):
  2991. """Initialize ScatterAdd"""
  2992. validator.check_value_type('use_locking', use_locking, [bool], self.name)
  2993. self.init_prim_io_names(inputs=['x', 'indices', 'updates'], outputs=['y'])
  2994. self.add_prim_attr('side_effect_mem', True)
  2995. class ScatterSub(_ScatterOp):
  2996. r"""
  2997. Updates the value of the input tensor through the subtraction operation.
  2998. Using given values to update tensor value through the subtraction operation, along with the input indices.
  2999. This operation outputs the `input_x` after the update is done, which makes it convenient to use the updated value.
  3000. for each `i, ..., j` in `indices.shape`:
  3001. .. math::
  3002. \text{input_x}[\text{indices}[i, ..., j], :] \mathrel{-}= \text{updates}[i, ..., j, :]
  3003. Inputs of `input_x` and `updates` comply with the implicit type conversion rules to make the data types consistent.
  3004. If they have different data types, lower priority data type will be converted to
  3005. relatively highest priority data type.
  3006. RuntimeError exception will be thrown when the data type conversion of Parameter is required.
  3007. Args:
  3008. use_locking (bool): Whether protect the assignment by a lock. Default: False.
  3009. Inputs:
  3010. - **input_x** (Parameter) - The target parameter.
  3011. - **indices** (Tensor) - The index to perform the subtraction operation
  3012. whose data type must be mindspore.int32.
  3013. - **updates** (Tensor) - The tensor that performs the subtraction operation with `input_x`,
  3014. the data type is the same as `input_x`, the shape is `indices_shape + x_shape[1:]`.
  3015. Outputs:
  3016. Parameter, the updated `input_x`.
  3017. Raises:
  3018. TypeError: If `use_locking` is not a bool.
  3019. Supported Platforms:
  3020. ``Ascend``
  3021. Examples:
  3022. >>> input_x = Parameter(Tensor(np.array([[0.0, 0.0, 0.0], [1.0, 1.0, 1.0]]), mindspore.float32), name="x")
  3023. >>> indices = Tensor(np.array([[0, 1]]), mindspore.int32)
  3024. >>> updates = Tensor(np.array([[[1.0, 1.0, 1.0], [2.0, 2.0, 2.0]]]), mindspore.float32)
  3025. >>> scatter_sub = ops.ScatterSub()
  3026. >>> output = scatter_sub(input_x, indices, updates)
  3027. >>> print(output)
  3028. [[-1. -1. -1.]
  3029. [-1. -1. -1.]]
  3030. """
  3031. class ScatterMul(_ScatterOp):
  3032. r"""
  3033. Updates the value of the input tensor through the multiply operation.
  3034. Using given values to update tensor value through the mul operation, along with the input indices.
  3035. This operation outputs the `input_x` after the update is done, which makes it convenient to use the updated value.
  3036. for each `i, ..., j` in `indices.shape`:
  3037. .. math::
  3038. \text{input_x}[\text{indices}[i, ..., j], :] \mathrel{*}= \text{updates}[i, ..., j, :]
  3039. Inputs of `input_x` and `updates` comply with the implicit type conversion rules to make the data types consistent.
  3040. If they have different data types, lower priority data type will be converted to
  3041. relatively highest priority data type.
  3042. RuntimeError exception will be thrown when the data type conversion of Parameter is required.
  3043. Args:
  3044. use_locking (bool): Whether protect the assignment by a lock. Default: False.
  3045. Inputs:
  3046. - **input_x** (Parameter) - The target parameter.
  3047. - **indices** (Tensor) - The index to do mul operation whose data type must be mindspore.int32.
  3048. - **updates** (Tensor) - The tensor doing the mul operation with `input_x`,
  3049. the data type is same as `input_x`, the shape is `indices_shape + x_shape[1:]`.
  3050. Outputs:
  3051. Parameter, the updated `input_x`.
  3052. Raises:
  3053. TypeError: If `use_locking` is not a bool.
  3054. Supported Platforms:
  3055. ``Ascend``
  3056. Examples:
  3057. >>> input_x = Parameter(Tensor(np.array([[1.0, 1.0, 1.0], [2.0, 2.0, 2.0]]), mindspore.float32), name="x")
  3058. >>> indices = Tensor(np.array([0, 1]), mindspore.int32)
  3059. >>> updates = Tensor(np.array([[2.0, 2.0, 2.0], [2.0, 2.0, 2.0]]), mindspore.float32)
  3060. >>> scatter_mul = ops.ScatterMul()
  3061. >>> output = scatter_mul(input_x, indices, updates)
  3062. >>> print(output)
  3063. [[2. 2. 2.]
  3064. [4. 4. 4.]]
  3065. """
  3066. class ScatterDiv(_ScatterOp):
  3067. r"""
  3068. Updates the value of the input tensor through the divide operation.
  3069. Using given values to update tensor value through the div operation, along with the input indices.
  3070. This operation outputs the `input_x` after the update is done, which makes it convenient to use the updated value.
  3071. for each `i, ..., j` in `indices.shape`:
  3072. .. math::
  3073. \text{input_x}[\text{indices}[i, ..., j], :] \mathrel{/}= \text{updates}[i, ..., j, :]
  3074. Inputs of `input_x` and `updates` comply with the implicit type conversion rules to make the data types consistent.
  3075. If they have different data types, lower priority data type will be converted to
  3076. relatively highest priority data type.
  3077. RuntimeError exception will be thrown when the data type conversion of Parameter is required.
  3078. Args:
  3079. use_locking (bool): Whether protect the assignment by a lock. Default: False.
  3080. Inputs:
  3081. - **input_x** (Parameter) - The target parameter.
  3082. - **indices** (Tensor) - The index to do div operation whose data type must be mindspore.int32.
  3083. - **updates** (Tensor) - The tensor that performs the div operation with `input_x`,
  3084. the data type is the same as `input_x`, the shape is `indices_shape + x_shape[1:]`.
  3085. Outputs:
  3086. Parameter, the updated `input_x`.
  3087. Raises:
  3088. TypeError: If `use_locking` is not a bool.
  3089. Supported Platforms:
  3090. ``Ascend``
  3091. Examples:
  3092. >>> input_x = Parameter(Tensor(np.array([[6.0, 6.0, 6.0], [2.0, 2.0, 2.0]]), mindspore.float32), name="x")
  3093. >>> indices = Tensor(np.array([0, 1]), mindspore.int32)
  3094. >>> updates = Tensor(np.array([[2.0, 2.0, 2.0], [2.0, 2.0, 2.0]]), mindspore.float32)
  3095. >>> scatter_div = ops.ScatterDiv()
  3096. >>> output = scatter_div(input_x, indices, updates)
  3097. >>> print(output)
  3098. [[3. 3. 3.]
  3099. [1. 1. 1.]]
  3100. """
  3101. class ScatterNdAdd(_ScatterNdOp):
  3102. r"""
  3103. Applies sparse addition to individual values or slices in a tensor.
  3104. Using given values to update tensor value through the add operation, along with the input indices.
  3105. This operation outputs the `input_x` after the update is done, which makes it convenient to use the updated value.
  3106. `input_x` has rank P and `indices` has rank Q where `Q >= 2`.
  3107. `indices` has shape :math:`(i_0, i_1, ..., i_{Q-2}, N)` where `N <= P`.
  3108. The last dimension of `indices` (with length `N` ) indicates slices along the `N` th dimension of `input_x`.
  3109. `updates` is a tensor of rank `Q-1+P-N`. Its shape is:
  3110. :math:`(i_0, i_1, ..., i_{Q-2}, x\_shape_N, ..., x\_shape_{P-1})`.
  3111. Inputs of `input_x` and `updates` comply with the implicit type conversion rules to make the data types consistent.
  3112. If they have different data types, lower priority data type will be converted to
  3113. relatively highest priority data type.
  3114. RuntimeError exception will be thrown when the data type conversion of Parameter is required.
  3115. Args:
  3116. use_locking (bool): Whether protect the assignment by a lock. Default: False.
  3117. Inputs:
  3118. - **input_x** (Parameter) - The target parameter.
  3119. - **indices** (Tensor) - The index to do add operation whose data type must be mindspore.int32.
  3120. The rank of indices must be at least 2 and `indices_shape[-1] <= len(shape)`.
  3121. - **updates** (Tensor) - The tensor doing the add operation with `input_x`,
  3122. the data type is same as `input_x`, the shape is `indices_shape[:-1] + x_shape[indices_shape[-1]:]`.
  3123. Outputs:
  3124. Parameter, the updated `input_x`.
  3125. Raises:
  3126. TypeError: If `use_locking` is not a bool.
  3127. Supported Platforms:
  3128. ``Ascend``
  3129. Examples:
  3130. >>> input_x = Parameter(Tensor(np.array([1, 2, 3, 4, 5, 6, 7, 8]), mindspore.float32), name="x")
  3131. >>> indices = Tensor(np.array([[2], [4], [1], [7]]), mindspore.int32)
  3132. >>> updates = Tensor(np.array([6, 7, 8, 9]), mindspore.float32)
  3133. >>> scatter_nd_add = ops.ScatterNdAdd()
  3134. >>> output = scatter_nd_add(input_x, indices, updates)
  3135. >>> print(output)
  3136. [ 1. 10. 9. 4. 12. 6. 7. 17.]
  3137. """
  3138. class ScatterNdSub(_ScatterNdOp):
  3139. r"""
  3140. Applies sparse subtraction to individual values or slices in a tensor.
  3141. Using given values to update tensor value through the subtraction operation, along with the input indices.
  3142. This operation outputs the `input_x` after the update is done, which makes it convenient to use the updated value.
  3143. `input_x` has rank P and `indices` has rank Q where `Q >= 2`.
  3144. `indices` has shape :math:`(i_0, i_1, ..., i_{Q-2}, N)` where `N <= P`.
  3145. The last dimension of `indices` (with length `N` ) indicates slices along the `N` th dimension of `input_x`.
  3146. `updates` is a tensor of rank `Q-1+P-N`. Its shape is:
  3147. :math:`(i_0, i_1, ..., i_{Q-2}, x\_shape_N, ..., x\_shape_{P-1})`.
  3148. Inputs of `input_x` and `updates` comply with the implicit type conversion rules to make the data types consistent.
  3149. If they have different data types, lower priority data type will be converted to
  3150. relatively highest priority data type.
  3151. RuntimeError exception will be thrown when the data type conversion of Parameter is required.
  3152. Args:
  3153. use_locking (bool): Whether protect the assignment by a lock. Default: False.
  3154. Inputs:
  3155. - **input_x** (Parameter) - The target parameter.
  3156. - **indices** (Tensor) - The index to do add operation whose data type must be mindspore.int32.
  3157. The rank of indices must be at least 2 and `indices_shape[-1] <= len(shape)`.
  3158. - **updates** (Tensor) - The tensor that performs the subtraction operation with `input_x`,
  3159. the data type is the same as `input_x`, the shape is `indices_shape[:-1] + x_shape[indices_shape[-1]:]`.
  3160. Outputs:
  3161. Parameter, the updated `input_x`.
  3162. Raises:
  3163. TypeError: If `use_locking` is not a bool.
  3164. Supported Platforms:
  3165. ``Ascend``
  3166. Examples:
  3167. >>> input_x = Parameter(Tensor(np.array([1, 2, 3, 4, 5, 6, 7, 8]), mindspore.float32), name="x")
  3168. >>> indices = Tensor(np.array([[2], [4], [1], [7]]), mindspore.int32)
  3169. >>> updates = Tensor(np.array([6, 7, 8, 9]), mindspore.float32)
  3170. >>> scatter_nd_sub = ops.ScatterNdSub()
  3171. >>> output = scatter_nd_sub(input_x, indices, updates)
  3172. >>> print(output)
  3173. [ 1. -6. -3. 4. -2. 6. 7. -1.]
  3174. """
  3175. class ScatterNonAliasingAdd(_ScatterNdOp):
  3176. """
  3177. Applies sparse addition to the input using individual values or slices.
  3178. Using given values to update tensor value through the add operation, along with the input indices.
  3179. This operation outputs the `input_x` after the update is done, which makes it convenient to use the updated value.
  3180. Inputs of `input_x` and `updates` comply with the implicit type conversion rules to make the data types consistent.
  3181. If they have different data types, lower priority data type will be converted to
  3182. relatively highest priority data type.
  3183. RuntimeError exception will be thrown when the data type conversion of Parameter is required.
  3184. Inputs:
  3185. - **input_x** (Parameter) - The target parameter. The data type must be float16, float32 or int32.
  3186. - **indices** (Tensor) - The index to perform the addition operation whose data type must be mindspore.int32.
  3187. - **updates** (Tensor) - The tensor that performs the addition operation with `input_x`,
  3188. the data type is the same as `input_x`, the shape is `indices_shape[:-1] + x_shape[indices_shape[-1]:]`.
  3189. Outputs:
  3190. Parameter, the updated `input_x`.
  3191. Raises:
  3192. TypeError: If dtype of `indices` is not int32.
  3193. TypeError: If dtype of `input_x` is not one of float16, float32, int32.
  3194. Supported Platforms:
  3195. ``Ascend``
  3196. Examples:
  3197. >>> input_x = Parameter(Tensor(np.array([1, 2, 3, 4, 5, 6, 7, 8]), mindspore.float32), name="x")
  3198. >>> indices = Tensor(np.array([[2], [4], [1], [7]]), mindspore.int32)
  3199. >>> updates = Tensor(np.array([6, 7, 8, 9]), mindspore.float32)
  3200. >>> scatter_non_aliasing_add = ops.ScatterNonAliasingAdd()
  3201. >>> output = scatter_non_aliasing_add(input_x, indices, updates)
  3202. >>> print(output)
  3203. [ 1. 10. 9. 4. 12. 6. 7. 17.]
  3204. """
  3205. @prim_attr_register
  3206. def __init__(self):
  3207. """Initialize ScatterNonAliasingAdd"""
  3208. self.init_prim_io_names(inputs=['x', 'indices', 'updates'], outputs=['y'])
  3209. self.add_prim_attr('side_effect_mem', True)
  3210. def infer_dtype(self, x_dtype, indices_dtype, updates_dtype):
  3211. validator.check_tensor_dtype_valid('indices', indices_dtype, [mstype.int32], self.name)
  3212. args = {"x": x_dtype, "updates": updates_dtype}
  3213. validator.check_tensors_dtypes_same_and_valid(args, [mstype.float16, mstype.float32, mstype.int32], self.name)
  3214. return x_dtype
  3215. class SpaceToDepth(PrimitiveWithInfer):
  3216. r"""
  3217. Rearranges blocks of spatial data into depth.
  3218. The output tensor's `height` dimension is :math:`height / block\_size`.
  3219. The output tensor's `weight` dimension is :math:`weight / block\_size`.
  3220. The depth of output tensor is :math:`block\_size * block\_size * input\_depth`.
  3221. The input tensor's height and width must be divisible by `block_size`.
  3222. The data format is "NCHW".
  3223. Args:
  3224. block_size (int): The block size used to divide spatial data. It must be >= 2.
  3225. Inputs:
  3226. - **x** (Tensor) - The target tensor.
  3227. Outputs:
  3228. Tensor, the same data type as `x`. It must be a 4-D tensor.
  3229. Raises:
  3230. TypeError: If `block_size` is not an int.
  3231. ValueError: If `block_size` is less than 2.
  3232. ValueError: If length of shape of `x` is not equal to 4.
  3233. Supported Platforms:
  3234. ``Ascend``
  3235. Examples:
  3236. >>> x = Tensor(np.random.rand(1,3,2,2), mindspore.float32)
  3237. >>> block_size = 2
  3238. >>> space_to_depth = ops.SpaceToDepth(block_size)
  3239. >>> output = space_to_depth(x)
  3240. >>> print(output.shape)
  3241. (1, 12, 1, 1)
  3242. """
  3243. @prim_attr_register
  3244. def __init__(self, block_size):
  3245. """Initialize SpaceToDepth"""
  3246. self.init_prim_io_names(inputs=['x'], outputs=['y'])
  3247. validator.check_value_type('block_size', block_size, [int], self.name)
  3248. validator.check('block_size', block_size, '', 2, Rel.GE)
  3249. self.block_size = block_size
  3250. self.add_prim_attr("data_format", "NCHW")
  3251. def infer_shape(self, x_shape):
  3252. validator.check('x dimension', len(x_shape), '', 4, Rel.EQ)
  3253. out_shape = copy.deepcopy(x_shape)
  3254. for i in range(2):
  3255. if out_shape[i + 2] % self.block_size != 0:
  3256. raise ValueError(f'For \'{self.name}\' input shape[{i + 2}] {out_shape[i + 2]} should be '
  3257. f'fully divided by block_size {self.block_size}')
  3258. out_shape[i + 2] //= self.block_size
  3259. out_shape[1] *= self.block_size * self.block_size
  3260. return out_shape
  3261. def infer_dtype(self, x_dtype):
  3262. validator.check_subclass("x_dtype", x_dtype, mstype.tensor, self.name)
  3263. return x_dtype
  3264. class DepthToSpace(PrimitiveWithInfer):
  3265. r"""
  3266. Rearranges blocks of depth data into spatial dimensions.
  3267. This is the reverse operation of SpaceToDepth.
  3268. The depth of output tensor is :math:`input\_depth / (block\_size * block\_size)`.
  3269. The output tensor's `height` dimension is :math:`height * block\_size`.
  3270. The output tensor's `weight` dimension is :math:`weight * block\_size`.
  3271. The input tensor's depth must be divisible by `block_size * block_size`.
  3272. The data format is "NCHW".
  3273. Args:
  3274. block_size (int): The block size used to divide depth data. It must be >= 2.
  3275. Inputs:
  3276. - **x** (Tensor) - The target tensor. It must be a 4-D tensor with shape :math:`(N, C_{in}, H_{in}, W_{in})`.
  3277. Outputs:
  3278. Tensor of shape :math:`(N, C_{in} / \text{block_size}, H_{in} * \text{block_size}, W_{in} * \text{block_size})`.
  3279. Raises:
  3280. TypeError: If `block_size` is not an int.
  3281. ValueError: If `block_size` is less than 2.
  3282. ValueError: If length of shape of `x` is not equal to 4.
  3283. Supported Platforms:
  3284. ``Ascend``
  3285. Examples:
  3286. >>> x = Tensor(np.random.rand(1, 12, 1, 1), mindspore.float32)
  3287. >>> block_size = 2
  3288. >>> depth_to_space = ops.DepthToSpace(block_size)
  3289. >>> output = depth_to_space(x)
  3290. >>> print(output.shape)
  3291. (1, 3, 2, 2)
  3292. """
  3293. @prim_attr_register
  3294. def __init__(self, block_size):
  3295. """Initialize DepthToSpace"""
  3296. self.init_prim_io_names(inputs=['x'], outputs=['y'])
  3297. validator.check_value_type('block_size', block_size, [int], self.name)
  3298. validator.check('block_size', block_size, '', 2, Rel.GE, self.name)
  3299. self.block_size = block_size
  3300. self.add_prim_attr("data_format", "NCHW")
  3301. def infer_shape(self, x_shape):
  3302. validator.check('x dimension', len(x_shape), '', 4, Rel.EQ)
  3303. out_shape = copy.deepcopy(x_shape)
  3304. for i in range(2):
  3305. out_shape[i + 2] *= self.block_size
  3306. validator.check_int(x_shape[1] % (self.block_size * self.block_size),
  3307. 0, Rel.EQ, 'x_shape[1] % (block_size*block_size)', self.name)
  3308. out_shape[1] //= self.block_size * self.block_size
  3309. return out_shape
  3310. def infer_dtype(self, x_dtype):
  3311. validator.check_subclass("x_dtype", x_dtype, mstype.tensor, self.name)
  3312. return x_dtype
  3313. class SpaceToBatch(PrimitiveWithInfer):
  3314. r"""
  3315. Divides spatial dimensions into blocks and combines the block size with the original batch.
  3316. This operation will divide spatial dimensions (H, W) into blocks with `block_size`, the output tensor's H and W
  3317. dimension is the corresponding number of blocks after division. The output tensor's batch dimension is the
  3318. product of the original batch and the square of block_size. Before division, the spatial dimensions
  3319. of the input are zero padded according to paddings if necessary.
  3320. Args:
  3321. block_size (int): The block size of dividing blocks with value greater than or euqual to 2.
  3322. paddings (Union[tuple, list]): The padding values for H and W dimension, containing 2 subtraction lists.
  3323. Each subtraction list contains 2 integer value. All values must be greater than 0.
  3324. paddings[i] specifies the paddings for the spatial dimension i, which corresponds to the
  3325. input dimension i+2. It is required that input_shape[i+2]+paddings[i][0]+paddings[i][1]
  3326. is divisible by block_size.
  3327. Inputs:
  3328. - **input_x** (Tensor) - The input tensor. It must be a 4-D tensor.
  3329. Outputs:
  3330. Tensor, the output tensor with the same data type as input. Assume input shape is :math:`(n, c, h, w)` with
  3331. :math:`block\_size` and :math:`paddings`. The shape of the output tensor will be :math:`(n', c', h', w')`,
  3332. where
  3333. :math:`n' = n*(block\_size*block\_size)`
  3334. :math:`c' = c`
  3335. :math:`h' = (h+paddings[0][0]+paddings[0][1])//block\_size`
  3336. :math:`w' = (w+paddings[1][0]+paddings[1][1])//block\_size`
  3337. Raises:
  3338. TypeError: If `block_size` is not an int.
  3339. ValueError: If `block_size` is less than 2.
  3340. Supported Platforms:
  3341. ``Ascend``
  3342. Examples:
  3343. >>> block_size = 2
  3344. >>> paddings = [[0, 0], [0, 0]]
  3345. >>> space_to_batch = ops.SpaceToBatch(block_size, paddings)
  3346. >>> input_x = Tensor(np.array([[[[1, 2], [3, 4]]]]), mindspore.float32)
  3347. >>> output = space_to_batch(input_x)
  3348. >>> print(output)
  3349. [[[[1.]]]
  3350. [[[2.]]]
  3351. [[[3.]]]
  3352. [[[4.]]]]
  3353. """
  3354. @prim_attr_register
  3355. def __init__(self, block_size, paddings):
  3356. """Initialize SpaceToBatch"""
  3357. logger.warning("WARN_DEPRECATED: The usage of SpaceToBatch is deprecated."
  3358. " Please use SpaceToBatchND.")
  3359. validator.check_value_type('block_size', block_size, [int], self.name)
  3360. validator.check('block_size', block_size, '', 2, Rel.GE, self.name)
  3361. self.block_size = block_size
  3362. validator.check('paddings shape', np.array(paddings).shape, '', (2, 2), Rel.EQ, self.name)
  3363. for elem in itertools.chain(*paddings):
  3364. validator.check_non_negative_int(elem, 'paddings element', self.name)
  3365. validator.check_value_type('paddings element', elem, [int], self.name)
  3366. self.paddings = paddings
  3367. def infer_dtype(self, x_dtype):
  3368. validator.check_tensor_dtype_valid('input_x', x_dtype, mstype.number_type, self.name)
  3369. return x_dtype
  3370. def infer_shape(self, x_shape):
  3371. validator.check_equal_int(len(x_shape), 4, 'rank of input_x', self.name)
  3372. out_shape = copy.deepcopy(x_shape)
  3373. for i in range(2):
  3374. padded = out_shape[i + 2] + self.paddings[i][0] + self.paddings[i][1]
  3375. if padded % self.block_size != 0:
  3376. raise ValueError(f'For \'{self.name}\' padded[{i}] {padded} should be divisible by '
  3377. f'block_size {self.block_size}')
  3378. out_shape[i + 2] = padded // self.block_size
  3379. out_shape[0] *= self.block_size * self.block_size
  3380. return out_shape
  3381. class BatchToSpace(PrimitiveWithInfer):
  3382. r"""
  3383. Divides batch dimension with blocks and interleaves these blocks back into spatial dimensions.
  3384. This operation will divide batch dimension N into blocks with block_size, the output tensor's N dimension
  3385. is the corresponding number of blocks after division. The output tensor's H, W dimension is product of original H, W
  3386. dimension and block_size with given amount to crop from dimension, respectively.
  3387. Args:
  3388. block_size (int): The block size of division, has the value not less than 2.
  3389. crops (Union[list(int), tuple(int)]): The crop value for H and W dimension, containing 2 subtraction lists.
  3390. Each list contains 2 integers.
  3391. All values must be not less than 0. crops[i] specifies the crop values for the spatial dimension i, which
  3392. corresponds to the input dimension i+2. It is required that
  3393. input_shape[i+2]*block_size >= crops[i][0]+crops[i][1].
  3394. Inputs:
  3395. - **input_x** (Tensor) - The input tensor. It must be a 4-D tensor, dimension 0 must be divisible by
  3396. product of `block_shape`.
  3397. Outputs:
  3398. Tensor, the output tensor with the same type as input. Assume input shape is (n, c, h, w) with block_size
  3399. and crops. The output shape will be (n', c', h', w'), where
  3400. :math:`n' = n//(block\_size*block\_size)`
  3401. :math:`c' = c`
  3402. :math:`h' = h*block\_size-crops[0][0]-crops[0][1]`
  3403. :math:`w' = w*block\_size-crops[1][0]-crops[1][1]`
  3404. Raises:
  3405. TypeError: If `block_size` or element of `crops` is not an int.
  3406. TypeError: If `crops` is neither list nor tuple.
  3407. ValueError: If `block_size` is less than 2.
  3408. Supported Platforms:
  3409. ``Ascend``
  3410. Examples:
  3411. >>> block_size = 2
  3412. >>> crops = [[0, 0], [0, 0]]
  3413. >>> batch_to_space = ops.BatchToSpace(block_size, crops)
  3414. >>> input_x = Tensor(np.array([[[[1]]], [[[2]]], [[[3]]], [[[4]]]]), mindspore.float32)
  3415. >>> output = batch_to_space(input_x)
  3416. >>> print(output)
  3417. [[[[1. 2.]
  3418. [3. 4.]]]]
  3419. """
  3420. @prim_attr_register
  3421. def __init__(self, block_size, crops):
  3422. """Initialize BatchToSpace"""
  3423. logger.warning("WARN_DEPRECATED: The usage of BatchToSpace is deprecated."
  3424. " Please use BatchToSpaceND.")
  3425. validator.check_value_type('block_size', block_size, [int], self.name)
  3426. validator.check('block_size', block_size, '', 2, Rel.GE, self.name)
  3427. self.block_size = block_size
  3428. validator.check_value_type('crops type', crops, [list, tuple], self.name)
  3429. validator.check('crops shape', np.array(crops).shape, '', (2, 2))
  3430. for elem in itertools.chain(*crops):
  3431. validator.check_non_negative_int(elem, 'crops element', self.name)
  3432. validator.check_value_type('crops element', elem, [int], self.name)
  3433. self.crops = crops
  3434. def infer_dtype(self, x_dtype):
  3435. validator.check_tensor_dtype_valid('input_x', x_dtype, mstype.number_type, self.name)
  3436. return x_dtype
  3437. def infer_shape(self, x_shape):
  3438. validator.check('rank of input_x', len(x_shape), '', 4)
  3439. out_shape = copy.deepcopy(x_shape)
  3440. for i in range(2):
  3441. x_block_prod = out_shape[i + 2] * self.block_size
  3442. crops_sum = self.crops[i][0] + self.crops[i][1]
  3443. validator.check("x block shape prod", x_block_prod, 'crops sum', crops_sum, Rel.GT, self.name)
  3444. out_shape[i + 2] = x_block_prod - crops_sum
  3445. block_size_prod = self.block_size * self.block_size
  3446. if out_shape[0] % block_size_prod != 0:
  3447. raise ValueError(f'For \'{self.name}\' input_x dimension 0 {out_shape[0]} should be divisible by '
  3448. f'block_size_prod {block_size_prod}')
  3449. out_shape[0] = out_shape[0] // block_size_prod
  3450. return out_shape
  3451. class SpaceToBatchND(PrimitiveWithInfer):
  3452. r"""
  3453. Divides spatial dimensions into blocks and combines the block size with the original batch.
  3454. This operation will divide spatial dimensions (H, W) into blocks with block_shape, the output tensor's H and W
  3455. dimension is the corresponding number of blocks after division. The output tensor's batch dimension is the
  3456. product of the original batch and the product of `block_shape`. Before division,
  3457. the spatial dimensions of the input are zero padded according to paddings if necessary.
  3458. Args:
  3459. block_shape (Union[list(int), tuple(int), int]): The block shape of dividing block with all value greater
  3460. than 1. If `block_shape` is a tuple or list, the length of `block_shape` is M corresponding to the
  3461. number of spatial dimensions. If `block_shape` is a int, the block size of M dimendions are the same,
  3462. equal to `block_shape`. M must be 2.
  3463. paddings (Union[tuple, list]): The padding values for H and W dimension, containing 2 subtraction list.
  3464. Each contains 2 integer value. All values must be greater than 0.
  3465. `paddings[i]` specifies the paddings for the spatial dimension i,
  3466. which corresponds to the input dimension i+2.
  3467. It is required that input_shape[i+2]+paddings[i][0]+paddings[i][1] is divisible by block_shape[i].
  3468. Inputs:
  3469. - **input_x** (Tensor) - The input tensor. It must be a 4-D tensor.
  3470. Outputs:
  3471. Tensor, the output tensor with the same data type as input. Assume input shape is :math:`(n, c, h, w)` with
  3472. :math:`block\_shape` and :math:`padddings`. The shape of the output tensor will be :math:`(n', c', h', w')`,
  3473. where
  3474. :math:`n' = n*(block\_shape[0]*block\_shape[1])`
  3475. :math:`c' = c`
  3476. :math:`h' = (h+paddings[0][0]+paddings[0][1])//block\_shape[0]`
  3477. :math:`w' = (w+paddings[1][0]+paddings[1][1])//block\_shape[1]`
  3478. Raises:
  3479. TypeError: If `block_shape` is not one of list, tuple, int.
  3480. TypeError: If `paddings` is neither list nor tuple.
  3481. ValueError: If length of shape of `block_shape` is not equal to 1.
  3482. ValueError: If length of `block_shape` or `paddings` is not equal to 2.
  3483. Supported Platforms:
  3484. ``Ascend``
  3485. Examples:
  3486. >>> block_shape = [2, 2]
  3487. >>> paddings = [[0, 0], [0, 0]]
  3488. >>> space_to_batch_nd = ops.SpaceToBatchND(block_shape, paddings)
  3489. >>> input_x = Tensor(np.array([[[[1, 2], [3, 4]]]]), mindspore.float32)
  3490. >>> output = space_to_batch_nd(input_x)
  3491. >>> print(output)
  3492. [[[[1.]]]
  3493. [[[2.]]]
  3494. [[[3.]]]
  3495. [[[4.]]]]
  3496. """
  3497. @prim_attr_register
  3498. def __init__(self, block_shape, paddings):
  3499. """Initialize SpaceToBatchND"""
  3500. if isinstance(block_shape, int):
  3501. block_shape = (block_shape,) * 2
  3502. self.add_prim_attr("block_shape", block_shape)
  3503. validator.check_value_type('block_shape type', block_shape, [list, tuple], self.name)
  3504. validator.check('block_shape shape', len(np.array(block_shape).shape), '', 1, Rel.EQ, self.name)
  3505. block_rank = len(block_shape)
  3506. validator.check('block_shape length', block_rank, '', 2, Rel.EQ, self.name)
  3507. for elem in block_shape:
  3508. validator.check('block_shape element', elem, '', 1, Rel.GE, self.name)
  3509. validator.check_value_type('block_shape element', elem, [int], self.name)
  3510. self.block_shape = block_shape
  3511. validator.check_value_type('paddings type', paddings, [list, tuple], self.name)
  3512. validator.check('paddings length', len(paddings), '', 2, Rel.EQ, self.name)
  3513. validator.check('paddings shape', np.array(paddings).shape, '', (block_rank, 2), Rel.EQ, self.name)
  3514. for elem in itertools.chain(*paddings):
  3515. validator.check_non_negative_int(elem, 'paddings element', self.name)
  3516. validator.check_value_type('paddings element', elem, [int], self.name)
  3517. self.paddings = paddings
  3518. def infer_dtype(self, x_dtype):
  3519. validator.check_tensor_dtype_valid('input_x', x_dtype, mstype.number_type, self.name)
  3520. return x_dtype
  3521. def infer_shape(self, x_shape):
  3522. x_rank = len(x_shape)
  3523. validator.check_equal_int(x_rank, 4, 'x_shape rank', self.name)
  3524. out_shape = copy.deepcopy(x_shape)
  3525. block_shape_prod = 1
  3526. offset = 2
  3527. for i in range(len(self.block_shape)):
  3528. padded = out_shape[i + offset] + self.paddings[i][0] + \
  3529. self.paddings[i][1]
  3530. if padded % self.block_shape[i] != 0:
  3531. raise ValueError(f'For \'{self.name}\' padded[{i}] {padded} should be divisible by '
  3532. f'block_shape[{i}] {self.block_shape[i]}')
  3533. out_shape[i + offset] = padded // self.block_shape[i]
  3534. block_shape_prod = block_shape_prod * self.block_shape[i]
  3535. out_shape[0] *= block_shape_prod
  3536. return out_shape
  3537. class BatchToSpaceND(PrimitiveWithInfer):
  3538. r"""
  3539. Divides batch dimension with blocks and interleaves these blocks back into spatial dimensions.
  3540. This operation will divide batch dimension N into blocks with block_shape, the output tensor's N dimension
  3541. is the corresponding number of blocks after division. The output tensor's H, W dimension is product of original H, W
  3542. dimension and block_shape with given amount to crop from dimension, respectively.
  3543. Args:
  3544. block_shape (Union[list(int), tuple(int), int]): The block shape of dividing block with all value greater
  3545. than 1. If `block_shape` is a tuple or list, the length of `block_shape` is M corresponding to the
  3546. number of spatial dimensions. If `block_shape` is a int, the block size of M dimendions are the same,
  3547. equal to `block_shape`. M must be 2.
  3548. crops (Union[list(int), tuple(int)]): The crop value for H and W dimension, containing 2 subtraction list,
  3549. each containing 2 int value.
  3550. All values must be >= 0. crops[i] specifies the crop values for spatial dimension i, which corresponds to
  3551. input dimension i+2. It is required that input_shape[i+2]*block_shape[i] > crops[i][0]+crops[i][1].
  3552. Inputs:
  3553. - **input_x** (Tensor) - The input tensor. It must be a 4-D tensor, dimension 0 must be divisible by
  3554. product of `block_shape`.
  3555. Outputs:
  3556. Tensor, the output tensor with the same type as input. Assume input shape is (n, c, h, w) with block_shape
  3557. and crops. The output shape will be (n', c', h', w'), where
  3558. :math:`n' = n//(block\_shape[0]*block\_shape[1])`
  3559. :math:`c' = c`
  3560. :math:`h' = h*block\_shape[0]-crops[0][0]-crops[0][1]`
  3561. :math:`w' = w*block\_shape[1]-crops[1][0]-crops[1][1]`
  3562. Raises:
  3563. TypeError: If `block_shape` is not one of list, tuple, int.
  3564. TypeError: If `crops` is neither list nor tuple.
  3565. ValueError: If length of `block_shape` or `crops` is not equal to 2.
  3566. Supported Platforms:
  3567. ``Ascend``
  3568. Examples:
  3569. >>> block_shape = [2, 2]
  3570. >>> crops = [[0, 0], [0, 0]]
  3571. >>> batch_to_space_nd = ops.BatchToSpaceND(block_shape, crops)
  3572. >>> input_x = Tensor(np.array([[[[1]]], [[[2]]], [[[3]]], [[[4]]]]), mindspore.float32)
  3573. >>> output = batch_to_space_nd(input_x)
  3574. >>> print(output)
  3575. [[[[1. 2.]
  3576. [3. 4.]]]]
  3577. """
  3578. @prim_attr_register
  3579. def __init__(self, block_shape, crops):
  3580. """Initialize BatchToSpaceND"""
  3581. if isinstance(block_shape, int):
  3582. block_shape = (block_shape,) * 2
  3583. self.add_prim_attr("block_shape", block_shape)
  3584. validator.check_value_type('block_shape type', block_shape, [list, tuple], self.name)
  3585. validator.check('block_shape shape', len(np.array(block_shape).shape), '', 1, Rel.EQ, self.name)
  3586. block_rank = len(block_shape)
  3587. validator.check('block_shape length', block_rank, '', 2, Rel.EQ, self.name)
  3588. for elem in block_shape:
  3589. validator.check('block_shape element', elem, '', 1, Rel.GE, self.name)
  3590. validator.check_value_type('block_shape element', elem, [int], self.name)
  3591. self.block_shape = block_shape
  3592. validator.check_value_type('crops type', crops, [list, tuple], self.name)
  3593. validator.check('crops length', len(crops), '', 2, Rel.EQ, self.name)
  3594. validator.check('crops shape', np.array(crops).shape, '', (block_rank, 2), Rel.EQ, self.name)
  3595. for elem in itertools.chain(*crops):
  3596. validator.check_non_negative_int(elem, 'crops element', self.name)
  3597. validator.check_value_type('crops element', elem, [int], self.name)
  3598. self.crops = crops
  3599. def infer_dtype(self, x_dtype):
  3600. validator.check_tensor_dtype_valid('input_x', x_dtype, mstype.number_type, self.name)
  3601. return x_dtype
  3602. def infer_shape(self, x_shape):
  3603. x_rank = len(x_shape)
  3604. validator.check_int(x_rank, 4, Rel.EQ, 'x_shape rank', self.name)
  3605. out_shape = copy.deepcopy(x_shape)
  3606. block_shape_prod = 1
  3607. offset = 2
  3608. for i in range(len(self.block_shape)):
  3609. block_shape_prod = block_shape_prod * self.block_shape[i]
  3610. x_block_prod = out_shape[i + offset] * self.block_shape[i]
  3611. crops_sum = self.crops[i][0] + self.crops[i][1]
  3612. validator.check("x block shape prod", x_block_prod, 'crops sum', crops_sum, Rel.GT, self.name)
  3613. out_shape[i + offset] = x_block_prod - crops_sum
  3614. if out_shape[0] % block_shape_prod != 0:
  3615. raise ValueError(f'For \'{self.name}\' input_x dimension 0 {out_shape[0]} should be divisible by '
  3616. f'block_shape_prod {block_shape_prod}')
  3617. out_shape[0] = out_shape[0] // block_shape_prod
  3618. return out_shape
  3619. class BroadcastTo(PrimitiveWithInfer):
  3620. """
  3621. Broadcasts input tensor to a given shape.
  3622. Input shape can be broadcast to target shape if for each dimension pair they are either equal or input is one or
  3623. the target dimension is -1. In case of -1 in target shape, it will be replaced by the input shape's value
  3624. in that dimension.
  3625. When input shape is broadcast to target shape, it starts with the trailing dimensions.
  3626. Args:
  3627. shape (tuple): The target shape to broadcast. Can be fully specified, or have -1 in one position
  3628. where it will be substituted by the input tensor's shape in that position, see example.
  3629. Inputs:
  3630. - **input_x** (Tensor) - The input tensor. The data type should be one of the following types: float16, float32,
  3631. int32, int8, uint8.
  3632. Outputs:
  3633. Tensor, with the given `shape` and the same data type as `input_x`.
  3634. Raises:
  3635. TypeError: If `shape` is not a tuple.
  3636. ValueError: Given a shape tuple, if it has several -1; or if the -1 is in an invalid position
  3637. such as one that does not have a opposing dimension in an input tensor; or if the target and
  3638. input shapes are incompatible.
  3639. Supported Platforms:
  3640. ``Ascend`` ``GPU``
  3641. Examples:
  3642. >>> shape = (2, 3)
  3643. >>> input_x = Tensor(np.array([1, 2, 3]).astype(np.float32))
  3644. >>> broadcast_to = ops.BroadcastTo(shape)
  3645. >>> output = broadcast_to(input_x)
  3646. >>> print(output)
  3647. [[1. 2. 3.]
  3648. [1. 2. 3.]]
  3649. >>> shape = (2, -1)
  3650. >>> input_x = Tensor(np.array([1, 2, 3]).astype(np.float32))
  3651. >>> broadcast_to = ops.BroadcastTo(shape)
  3652. >>> output = broadcast_to(input_x)
  3653. >>> print(output)
  3654. [[1. 2. 3.]
  3655. [1. 2. 3.]]
  3656. """
  3657. @prim_attr_register
  3658. def __init__(self, shape):
  3659. """Initialize BroadcastTo"""
  3660. validator.check_value_type("shape", shape, (tuple), self.name)
  3661. validator.check("shape length", len(shape), "", 0, Rel.GT, self.name)
  3662. for ix, i in enumerate(shape):
  3663. validator.check_value_type('target shape index -> ' + str(ix), i, [int], self.name)
  3664. validator.check("shape element", i, "shape element min limit", -1, Rel.GE, self.name)
  3665. self.shape = shape
  3666. if -1 in self.shape:
  3667. undef_dims = self.shape.count(-1)
  3668. if undef_dims > 1:
  3669. raise ValueError(f'The shape can only has one -1 at most, but has {undef_dims}.')
  3670. self.dyn = True
  3671. else:
  3672. self.dyn = False
  3673. def infer_shape(self, x_shape):
  3674. validator.check("input_x shape length", len(x_shape), "target shape", len(self.shape), Rel.LE, self.name)
  3675. target_shape = list(self.shape)
  3676. outer_dim_offset = len(target_shape) - len(x_shape)
  3677. if self.dyn:
  3678. for i, v in enumerate(target_shape):
  3679. if v == -1:
  3680. if i < outer_dim_offset:
  3681. raise ValueError(f" -1 in init shape is in an incompatible location"
  3682. f" with given input tensor, -1 index in init shape: {i}"
  3683. f" but -1 can only be in index {len(x_shape)} onwards for this input.")
  3684. target_shape[i] = x_shape[i - outer_dim_offset]
  3685. reversed_x_shape = tuple(reversed(x_shape))
  3686. reversed_target = tuple(reversed(target_shape))
  3687. for i, v in enumerate(reversed_x_shape):
  3688. if v not in (reversed_target[i], 1):
  3689. raise ValueError(f"Not supported shapes for broadcast, "
  3690. f"x_shape: {tuple(x_shape)}, target shape {target_shape}.")
  3691. self.shape = tuple(target_shape)
  3692. self.add_prim_attr('shape', self.shape)
  3693. return target_shape
  3694. def infer_dtype(self, x_dtype):
  3695. validator.check_subclass("input_x", x_dtype, mstype.tensor, self.name)
  3696. return x_dtype
  3697. class Meshgrid(PrimitiveWithInfer):
  3698. """
  3699. Generates coordinate matrices from given coordinate tensors.
  3700. Given N one-dimensional coordinate tensors, returns a tuple outputs of N N-D
  3701. coordinate tensors for evaluating expressions on an N-D grid.
  3702. Args:
  3703. indexing (str): Either 'xy' or 'ij'. Default: 'xy'.
  3704. When the indexing argument is set to 'xy' (the default), the broadcasting
  3705. instructions for the first two dimensions are swapped.
  3706. Inputs:
  3707. - **input** (Union[tuple]) - A Tuple of N 1-D Tensor objects.
  3708. The length of input should be greater than 1
  3709. Outputs:
  3710. Tensors, A Tuple of N N-D Tensor objects.
  3711. Raises:
  3712. TypeError: If `indexing` is not a str or `input` is not a tuple.
  3713. ValueError: If `indexing` is neither 'xy' nor 'ij'.
  3714. Supported Platforms:
  3715. ``Ascend``
  3716. Examples:
  3717. >>> x = Tensor(np.array([1, 2, 3, 4]).astype(np.int32))
  3718. >>> y = Tensor(np.array([5, 6, 7]).astype(np.int32))
  3719. >>> z = Tensor(np.array([8, 9, 0, 1, 2]).astype(np.int32))
  3720. >>> inputs = (x, y, z)
  3721. >>> meshgrid = ops.Meshgrid(indexing="xy")
  3722. >>> output = meshgrid(inputs)
  3723. >>> print(output)
  3724. (Tensor(shape=[3, 4, 5], dtype=Int32, value=
  3725. [[[1, 1, 1, 1, 1],
  3726. [2, 2, 2, 2, 2],
  3727. [3, 3, 3, 3, 3],
  3728. [4, 4, 4, 4, 4]],
  3729. [[1, 1, 1, 1, 1],
  3730. [2, 2, 2, 2, 2],
  3731. [3, 3, 3, 3, 3],
  3732. [4, 4, 4, 4, 4]],
  3733. [[1, 1, 1, 1, 1],
  3734. [2, 2, 2, 2, 2],
  3735. [3, 3, 3, 3, 3],
  3736. [4, 4, 4, 4, 4]]]),
  3737. Tensor(shape=[3, 4, 5], dtype=Int32, value=
  3738. [[[5, 5, 5, 5, 5],
  3739. [5, 5, 5, 5, 5],
  3740. [5, 5, 5, 5, 5],
  3741. [5, 5, 5, 5, 5]],
  3742. [[6, 6, 6, 6, 6],
  3743. [6, 6, 6, 6, 6],
  3744. [6, 6, 6, 6, 6],
  3745. [6, 6, 6, 6, 6]],
  3746. [[7, 7, 7, 7, 7],
  3747. [7, 7, 7, 7, 7],
  3748. [7, 7, 7, 7, 7],
  3749. [7, 7, 7, 7, 7]]]),
  3750. Tensor(shape=[3, 4, 5], dtype=Int32, value=
  3751. [[[8, 9, 0, 1, 2],
  3752. [8, 9, 0, 1, 2],
  3753. [8, 9, 0, 1, 2],
  3754. [8, 9, 0, 1, 2]],
  3755. [[8, 9, 0, 1, 2],
  3756. [8, 9, 0, 1, 2],
  3757. [8, 9, 0, 1, 2],
  3758. [8, 9, 0, 1, 2]],
  3759. [[8, 9, 0, 1, 2],
  3760. [8, 9, 0, 1, 2],
  3761. [8, 9, 0, 1, 2],
  3762. [8, 9, 0, 1, 2]]]))
  3763. """
  3764. @prim_attr_register
  3765. def __init__(self, indexing="xy"):
  3766. """Init Meshgrid"""
  3767. validator.check_value_type("indexing", indexing, (str), self.name)
  3768. if indexing not in ("xy", "ij"):
  3769. raise ValueError("indexing parameter must be either 'xy' or 'ij'")
  3770. self.indexing = indexing
  3771. def infer_shape(self, x_shape):
  3772. validator.check_value_type("shape", x_shape, [tuple], self.name)
  3773. validator.check_int(len(x_shape), 2, Rel.GE, "len of input", self.name)
  3774. n = len(x_shape)
  3775. shape_0 = []
  3776. for s in x_shape:
  3777. validator.check_int(len(s), 1, Rel.EQ, 'each input rank', self.name)
  3778. shape_0.append(s[0])
  3779. if self.indexing == "xy":
  3780. shape_0[0], shape_0[1] = shape_0[1], shape_0[0]
  3781. out_shape = tuple(tuple(shape_0) for _ in range(n))
  3782. return out_shape
  3783. def infer_dtype(self, x_type):
  3784. validator.check_subclass("input[0]", x_type[0], mstype.tensor, self.name)
  3785. n = len(x_type)
  3786. for i in range(1, n):
  3787. validator.check('x_type[%d]' % i, x_type[i], 'base', x_type[0], Rel.EQ, self.name, TypeError)
  3788. return x_type
  3789. class InplaceUpdate(PrimitiveWithInfer):
  3790. r"""
  3791. Updates specified rows with values in `v`.
  3792. Args:
  3793. indices (Union[int, tuple]): Indices into the left-most dimension of `x`, and determines which rows of x
  3794. to update with v. It is a int or tuple, whose value is in [0, the first dimension size of x).
  3795. Inputs:
  3796. - **x** (Tensor) - A tensor which to be inplace updated. It can be one of the following data types:
  3797. float32, float16 and int32.
  3798. - **v** (Tensor) - A tensor with the same type as `x` and the same dimension size as `x` except
  3799. the first dimension, which must be the same as the size of `indices`.
  3800. Outputs:
  3801. Tensor, with the same type and shape as the input `x`.
  3802. Raises:
  3803. TypeError: If `indices` is neither int nor tuple.
  3804. TypeError: If `indices` is a tuple and its element is not an int.
  3805. Supported Platforms:
  3806. ``Ascend``
  3807. Examples:
  3808. >>> indices = (0, 1)
  3809. >>> x = Tensor(np.array([[1, 2], [3, 4], [5, 6]]), mindspore.float32)
  3810. >>> v = Tensor(np.array([[0.5, 1.0], [1.0, 1.5]]), mindspore.float32)
  3811. >>> inplace_update = ops.InplaceUpdate(indices)
  3812. >>> output = inplace_update(x, v)
  3813. >>> print(output)
  3814. [[0.5 1. ]
  3815. [1. 1.5]
  3816. [5. 6. ]]
  3817. """
  3818. @prim_attr_register
  3819. def __init__(self, indices):
  3820. """Initialize InplaceUpdate"""
  3821. self.init_prim_io_names(inputs=['x', 'v'], outputs=['y'])
  3822. self.indices = indices
  3823. validator.check_value_type("indices", indices, [int, tuple], self.name)
  3824. if isinstance(indices, int):
  3825. self.indices = (indices,)
  3826. for item in self.indices:
  3827. validator.check_value_type("item of indices", item, [int], self.name)
  3828. def infer_dtype(self, x_dtype, v_dtype):
  3829. args = {'x': x_dtype, 'v': v_dtype}
  3830. valid_type = [mstype.int32, mstype.float16, mstype.float32]
  3831. validator.check_tensors_dtypes_same_and_valid(args, valid_type, self.name)
  3832. return x_dtype
  3833. def infer_shape(self, x_shape, v_shape):
  3834. validator.check("x", len(x_shape), "v", len(v_shape), Rel.EQ, self.name)
  3835. validator.check("size of indices", len(self.indices), "v's first dimension", v_shape[0],
  3836. Rel.EQ, self.name)
  3837. for i in self.indices:
  3838. if i < 0 or i >= x_shape[0]:
  3839. raise ValueError(f'The value of indices must be in [0, {x_shape[0]}), but got {i}.')
  3840. x_rank = len(x_shape)
  3841. for idx in range(x_rank)[1:]:
  3842. validator.check('v dim %d' % idx, v_shape[idx], "x dim %d" % idx, x_shape[idx], Rel.EQ, self.name)
  3843. return x_shape
  3844. class ReverseSequence(PrimitiveWithInfer):
  3845. """
  3846. Reverses variable length slices.
  3847. Args:
  3848. seq_dim (int): The dimension where reversal is performed. Required.
  3849. batch_dim (int): The input is sliced in this dimension. Default: 0.
  3850. Inputs:
  3851. - **x** (Tensor) - The input to reverse, supporting all number types including bool.
  3852. - **seq_lengths** (Tensor) - Must be a 1-D vector with int32 or int64 types.
  3853. Outputs:
  3854. Reversed tensor with the same shape and data type as input.
  3855. Raises:
  3856. TypeError: If `seq_dim` or `batch_dim` is not an int.
  3857. Supported Platforms:
  3858. ``Ascend``
  3859. Examples:
  3860. >>> x = Tensor(np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]), mindspore.float32)
  3861. >>> seq_lengths = Tensor(np.array([1, 2, 3]))
  3862. >>> reverse_sequence = ops.ReverseSequence(seq_dim=1)
  3863. >>> output = reverse_sequence(x, seq_lengths)
  3864. >>> print(output)
  3865. [[1. 2. 3.]
  3866. [5. 4. 6.]
  3867. [9. 8. 7.]]
  3868. """
  3869. @prim_attr_register
  3870. def __init__(self, seq_dim, batch_dim=0):
  3871. """Initialize ReverseSequence"""
  3872. self.init_prim_io_names(inputs=['x', 'seq_lengths'], outputs=['y'])
  3873. validator.check_value_type("seq_dim", seq_dim, [int], self.name)
  3874. self.seq_dim_ = seq_dim
  3875. validator.check_value_type("batch_dim", batch_dim, [int], self.name)
  3876. self.batch_dim_ = batch_dim
  3877. def infer_shape(self, x, seq_lengths):
  3878. validator.check("seq_dim", self.seq_dim_, "x rank", len(x), Rel.LE, self.name)
  3879. validator.check("batch_dim", self.batch_dim_, "x rank", len(x), Rel.LE, self.name)
  3880. validator.check("batch_dim", self.batch_dim_, "seq_dim", self.seq_dim_, Rel.NE, self.name)
  3881. validator.check("seq_lengths rank", len(seq_lengths), "expected", 1, Rel.EQ, self.name)
  3882. validator.check("seq_lengths vector size", seq_lengths[0],
  3883. "input size along batch_dim", x[self.batch_dim_], Rel.EQ, self.name)
  3884. return x
  3885. def infer_dtype(self, x, seq_lengths):
  3886. validator.check_tensor_dtype_valid("x_dtype", x, mstype.number_type + (mstype.bool_,), self.name)
  3887. validator.check_tensor_dtype_valid("seq_lengths_dtype", seq_lengths, [mstype.int32, mstype.int64], self.name)
  3888. return x
  3889. class EditDistance(PrimitiveWithInfer):
  3890. """
  3891. Computes the Levenshtein Edit Distance. It is used to measure the similarity of two sequences. The inputs are
  3892. variable-length sequences provided by SparseTensors (hypothesis_indices, hypothesis_values, hypothesis_shape)
  3893. and (truth_indices, truth_values, truth_shape).
  3894. Args:
  3895. normalize (bool): If true, edit distances are normalized by length of truth. Default: True.
  3896. Inputs:
  3897. - **hypothesis_indices** (Tensor) - The indices of the hypothesis list SparseTensor. With int64 data type.
  3898. The shape of tensor is :math:`(N, R)`.
  3899. - **hypothesis_values** (Tensor) - The values of the hypothesis list SparseTensor.
  3900. Must be 1-D vector with length of N.
  3901. - **hypothesis_shape** (Tensor) - The shape of the hypothesis list SparseTensor.
  3902. Must be R-length vector with int64 data type. Only constant value is allowed.
  3903. - **truth_indices** (Tensor) - The indices of the truth list SparseTensor. With int64 data type.
  3904. The shape of tensor is :math:`(M, R)`.
  3905. - **truth_values** (Tensor) - The values of the truth list SparseTensor. Must be 1-D vector with length of M.
  3906. - **truth_shape** (Tensor) - The shape of the truth list SparseTensor.
  3907. Must be R-length vector with int64 data type. Only constant value is allowed.
  3908. Outputs:
  3909. Tensor, a dense tensor with rank `R-1` and float32 data type.
  3910. Raises:
  3911. TypeError: If `normalize` is not a bool.
  3912. Supported Platforms:
  3913. ``Ascend``
  3914. Examples:
  3915. >>> import numpy as np
  3916. >>> from mindspore import context
  3917. >>> from mindspore import Tensor
  3918. >>> import mindspore.nn as nn
  3919. >>> import mindspore.ops.operations as ops
  3920. >>> class EditDistance(nn.Cell):
  3921. ... def __init__(self, hypothesis_shape, truth_shape, normalize=True):
  3922. ... super(EditDistance, self).__init__()
  3923. ... self.edit_distance = ops.EditDistance(normalize)
  3924. ... self.hypothesis_shape = hypothesis_shape
  3925. ... self.truth_shape = truth_shape
  3926. ...
  3927. ... def construct(self, hypothesis_indices, hypothesis_values, truth_indices, truth_values):
  3928. ... return self.edit_distance(hypothesis_indices, hypothesis_values, self.hypothesis_shape,
  3929. ... truth_indices, truth_values, self.truth_shape)
  3930. ...
  3931. >>> hypothesis_indices = Tensor(np.array([[0, 0, 0], [1, 0, 1], [1, 1, 1]]).astype(np.int64))
  3932. >>> hypothesis_values = Tensor(np.array([1, 2, 3]).astype(np.float32))
  3933. >>> hypothesis_shape = Tensor(np.array([1, 1, 2]).astype(np.int64))
  3934. >>> truth_indices = Tensor(np.array([[0, 1, 0], [0, 0, 1], [1, 1, 0], [1, 0, 1]]).astype(np.int64))
  3935. >>> truth_values = Tensor(np.array([1, 3, 2, 1]).astype(np.float32))
  3936. >>> truth_shape = Tensor(np.array([2, 2, 2]).astype(np.int64))
  3937. >>> edit_distance = EditDistance(hypothesis_shape, truth_shape)
  3938. >>> output = edit_distance(hypothesis_indices, hypothesis_values, truth_indices, truth_values)
  3939. >>> print(output)
  3940. [[1. 1.]
  3941. [1. 1.]]
  3942. """
  3943. @prim_attr_register
  3944. def __init__(self, normalize=True):
  3945. """Initialize EditDistance"""
  3946. self.normalize = validator.check_value_type("normalize", normalize, [bool], self.name)
  3947. self.set_const_input_indexes([2, 5])
  3948. def __infer__(self, h_indices, h_values, h_shape, truth_indices, truth_values, truth_shape):
  3949. validator.check_const_input('hypothesis_shape', h_shape['value'], self.name)
  3950. validator.check_const_input('truth_shape', truth_shape['value'], self.name)
  3951. args_int = {"hypothesis_indices": h_indices['dtype'], "hypothesis_shape": h_shape['dtype'],
  3952. "truth_indices": truth_indices['dtype'], "truth_shape": truth_shape['dtype']}
  3953. validator.check_tensors_dtypes_same_and_valid(args_int, [mstype.int64], self.name)
  3954. args = {"hypothesis_values": h_values['dtype'], "truth_values": truth_values['dtype']}
  3955. validator.check_tensors_dtypes_same_and_valid(args, mstype.number_type, self.name)
  3956. hypothesis_indices_shp, truth_indices_shp = h_indices['shape'], truth_indices['shape']
  3957. validator.check("hypothesis_indices rank", len(hypothesis_indices_shp), "expected", 2, Rel.EQ, self.name)
  3958. validator.check("truth_indices rank", len(truth_indices_shp), "expected", 2, Rel.EQ, self.name)
  3959. validator.check("hypothesis_values rank", len(h_values['shape']), "expected", 1, Rel.EQ, self.name)
  3960. validator.check("hypothesis_shape rank", len(h_shape['shape']), "expected", 1, Rel.EQ, self.name)
  3961. validator.check("truth_values rank", len(truth_values['shape']), "expected", 1, Rel.EQ, self.name)
  3962. validator.check("truth_shape rank", len(truth_shape['shape']), "expected", 1, Rel.EQ, self.name)
  3963. validator.check("hypothesis_values shape", h_values['shape'][0],
  3964. "hypothesis_indices shape[0]", hypothesis_indices_shp[0], Rel.EQ, self.name)
  3965. validator.check("hypothesis_shape", h_shape['shape'][0],
  3966. "hypothesis_indices shape[1]", hypothesis_indices_shp[1], Rel.EQ, self.name)
  3967. validator.check("truth_values shape", truth_values['shape'][0],
  3968. "truth_indices shape[0]", truth_indices_shp[0], Rel.EQ, self.name)
  3969. validator.check("hypothesis_shape", h_shape['shape'][0],
  3970. "truth_shape", truth_shape['shape'][0], Rel.EQ, self.name)
  3971. hypothesis_shape_v = h_shape['value'].asnumpy()
  3972. truth_shape_v = truth_shape['value'].asnumpy()
  3973. out_shape_rank = len(hypothesis_shape_v) - 1
  3974. out_shape = []
  3975. for i in range(out_shape_rank):
  3976. out_shape.append(max(hypothesis_shape_v[i], truth_shape_v[i]))
  3977. return {'shape': tuple(out_shape),
  3978. 'dtype': mstype.tensor_type(mstype.float32),
  3979. 'value': None}
  3980. class TransShape(PrimitiveWithInfer):
  3981. """
  3982. Transforms the shape of input tensor to target shape.
  3983. Inputs:
  3984. - **input_x** (Tensor) - A input tensor.
  3985. - **out_shape** (tuple[int]) - The shape of output data.
  3986. Outputs:
  3987. Tensor, a tensor whose data type is same as 'input_x', and the shape is the same as the `out_shape`.
  3988. """
  3989. @prim_attr_register
  3990. def __init__(self):
  3991. self.__setattr_flag__ = True
  3992. def __infer__(self, x, shape):
  3993. shp = shape['value']
  3994. dtype = x['dtype']
  3995. validator.check_tensor_dtype_valid('x', dtype, mstype.number_type + (mstype.bool_,), self.name)
  3996. self.add_prim_attr('out_shape', tuple(shp))
  3997. return {'shape': shp,
  3998. 'dtype': dtype,
  3999. 'value': None}
  4000. class Sort(PrimitiveWithInfer):
  4001. """
  4002. Sorts the elements of the input tensor along a given dimension in ascending order by value.
  4003. Args:
  4004. axis (int): The dimension to sort along. Default: -1.
  4005. descending (bool): Controls the sorting order. If descending is True then the elements
  4006. are sorted in descending order by value. Default: False.
  4007. Inputs:
  4008. - **x** (Tensor) - The input to sort, with float16 or float32 data type.
  4009. Outputs:
  4010. - **y1** (Tensor) - A tensor whose values are the sorted values, with the same shape and data type as input.
  4011. - **y2** (Tensor) - The indices of the elements in the original input tensor. Data type is int32.
  4012. Raises:
  4013. TypeError: If `axis` is not an int.
  4014. TypeError: If `descending` is not a bool.
  4015. TypeError: If dtype of `x` is neither float16 nor float32.
  4016. Supported Platforms:
  4017. ``Ascend``
  4018. Examples:
  4019. >>> x = Tensor(np.array([[8, 2, 1], [5, 9, 3], [4, 6, 7]]), mindspore.float16)
  4020. >>> sort = ops.Sort()
  4021. >>> output = sort(x)
  4022. >>> print(output)
  4023. (Tensor(shape=[3, 3], dtype=Float16, value=
  4024. [[ 1.0000e+00, 2.0000e+00, 8.0000e+00],
  4025. [ 3.0000e+00, 5.0000e+00, 9.0000e+00],
  4026. [ 4.0000e+00, 6.0000e+00, 7.0000e+00]]), Tensor(shape=[3, 3], dtype=Int32, value=
  4027. [[2, 1, 0],
  4028. [2, 0, 1],
  4029. [0, 1, 2]]))
  4030. """
  4031. @prim_attr_register
  4032. def __init__(self, axis=-1, descending=False):
  4033. """Initialize Sort"""
  4034. self.axis = validator.check_value_type("axis", axis, [int], self.name)
  4035. self.descending = validator.check_value_type("descending", descending, [bool], self.name)
  4036. def infer_shape(self, x_shape):
  4037. return x_shape, x_shape
  4038. def infer_dtype(self, x_dtype):
  4039. validator.check_tensor_dtype_valid("x_dtype", x_dtype, [mstype.float32, mstype.float16], self.name)
  4040. return x_dtype, mstype.tensor_type(mstype.int32)
  4041. class EmbeddingLookup(PrimitiveWithInfer):
  4042. """
  4043. Returns a slice of input tensor based on the specified indices.
  4044. This Primitive has the similar functionality as GatherV2 operating on `axis = 0`, but has one more inputs:
  4045. `offset`.
  4046. Inputs:
  4047. - **input_params** (Tensor) - The shape of tensor is :math:`(x_1, x_2, ..., x_R)`.
  4048. This represents a Tensor slice, instead of the entire Tensor. Currently, the dimension is restricted to be 2.
  4049. - **input_indices** (Tensor) - The shape of tensor is :math:`(y_1, y_2, ..., y_S)`.
  4050. Specifies the indices of elements of the original Tensor. Values can be out of range of `input_params`,
  4051. and the exceeding part will be filled with 0 in the output. Values does not support negative and the result
  4052. is undefined if values are negative.
  4053. - **offset** (int) - Specifies the offset value of this `input_params` slice. Thus the real indices
  4054. are equal to `input_indices` minus `offset`.
  4055. Outputs:
  4056. Tensor, the shape of tensor is :math:`(z_1, z_2, ..., z_N)`.
  4057. Raises:
  4058. TypeError: If dtype of `input_indices` is not int.
  4059. ValueError: If length of shape of `input_params` is greater than 2.
  4060. Supported Platforms:
  4061. ``Ascend`` ``CPU``
  4062. Examples:
  4063. >>> input_params = Tensor(np.array([[8, 9], [10, 11], [12, 13], [14, 15]]), mindspore.float32)
  4064. >>> input_indices = Tensor(np.array([[5, 2], [8, 5]]), mindspore.int32)
  4065. >>> offset = 4
  4066. >>> output = ops.EmbeddingLookup()(input_params, input_indices, offset)
  4067. >>> print(output)
  4068. [[[10. 11.]
  4069. [ 0. 0.]]
  4070. [[ 0. 0.]
  4071. [10. 11.]]]
  4072. """
  4073. @prim_attr_register
  4074. def __init__(self):
  4075. """Initialize index_select"""
  4076. self.__setattr_flag__ = True
  4077. self.init_prim_io_names(inputs=['params', 'indices', 'offset'],
  4078. outputs=['output'])
  4079. def __infer__(self, params, indices, offset):
  4080. validator.check_subclass("params", params['dtype'], mstype.tensor, self.name)
  4081. validator.check_tensor_dtype_valid("indices", indices['dtype'], mstype.int_type, self.name)
  4082. validator.check_subclass("offset", offset['dtype'], mstype.int_, self.name)
  4083. params_shp = params['shape']
  4084. if len(params_shp) > 2:
  4085. raise ValueError("The dimension of 'params' in EmbeddingLookup must <= 2, but got %d." % len(params_shp))
  4086. out_shape = indices['shape'] + params_shp[1:]
  4087. if 'max_shape' in indices:
  4088. out_max_shape = indices['max_shape'] + params_shp[1:]
  4089. else:
  4090. out_max_shape = out_shape
  4091. if 'min_shape' in indices:
  4092. out_min_shape = indices['min_shape'] + params_shp[1:]
  4093. else:
  4094. out_min_shape = out_shape
  4095. out = {'shape': out_shape,
  4096. 'dtype': params['dtype'],
  4097. 'value': None,
  4098. 'max_shape': out_max_shape,
  4099. 'min_shape': out_min_shape}
  4100. return out
  4101. class GatherD(PrimitiveWithInfer):
  4102. """
  4103. Gathers values along an axis specified by dim.
  4104. For a 3-D tensor, the output is:
  4105. output[i][j][k] = x[index[i][j][k]][j][k] # if dim == 0
  4106. output[i][j][k] = x[i][index[i][j][k]][k] # if dim == 1
  4107. output[i][j][k] = x[i][j][index[i][j][k]] # if dim == 2
  4108. If `x` is an n-D tensor with shape :math:`(z_0, z_1, ..., z_i, ..., z_{n-1})` and `dim` = i,
  4109. the `index` must be an n-D tensor with shape :math:`(z_0, z_1, ..., y, ..., z_{n-1})`
  4110. where `y`>=1 and the output will have the same shape as `index`.
  4111. Inputs:
  4112. - **x** (Tensor) - The source tensor.
  4113. - **dim** (int) - The axis along which to index. It must be int32 or int64. Only constant value is allowed.
  4114. - **index** (Tensor) - The indices of elements to gather. It can be one of the following data types:
  4115. int32, int64. The value range of each index element is [-x_rank[dim], x_rank[dim]).
  4116. Outputs:
  4117. Tensor, the shape of tensor is :math:`(z_1, z_2, ..., z_N)`.
  4118. Raises:
  4119. TypeError: If dtype of `dim` or `index` is neither int32 nor int64.
  4120. ValueError: If length of shape of `x` is not equal to length of shape of `index`.
  4121. Supported Platforms:
  4122. ``Ascend`` ``GPU`` ``CPU``
  4123. Examples:
  4124. >>> x = Tensor(np.array([[1, 2], [3, 4]]), mindspore.int32)
  4125. >>> index = Tensor(np.array([[0, 0], [1, 0]]), mindspore.int32)
  4126. >>> dim = 1
  4127. >>> output = ops.GatherD()(x, dim, index)
  4128. >>> print(output)
  4129. [[1 1]
  4130. [4 3]]
  4131. """
  4132. @prim_attr_register
  4133. def __init__(self):
  4134. """Initialize GatherD"""
  4135. self.init_prim_io_names(inputs=['x', 'dim', 'index'], outputs=['output'])
  4136. def __infer__(self, x, dim, index):
  4137. validator.check_subclass("x", x['dtype'], mstype.tensor, self.name)
  4138. validator.check_tensor_dtype_valid("index", index['dtype'], [mstype.int32, mstype.int64], self.name)
  4139. validator.check_subclass("dim", dim['dtype'], [mstype.int32, mstype.int64], self.name)
  4140. x_shp = x['shape']
  4141. idx_shp = index['shape']
  4142. x_rank = len(x_shp)
  4143. idx_rank = len(idx_shp)
  4144. validator.check("x_rank, idx_rank", x_rank, "expected", idx_rank, Rel.EQ, self.name)
  4145. dim_v = dim['value']
  4146. validator.check("dim value", dim_v, "expected", -x_rank, Rel.GE, self.name)
  4147. validator.check("dim value", dim_v, "expected", x_rank, Rel.LT, self.name)
  4148. if dim_v < 0:
  4149. dim['value'] = dim_v + x_rank
  4150. for i in range(x_rank):
  4151. if i == dim['value']:
  4152. continue
  4153. validator.check("x_shp[{0}], idx_shp[{0}]".format(i), x_shp[i], "expected", idx_shp[i], Rel.EQ, self.name)
  4154. out = {'shape': index['shape'],
  4155. 'dtype': x['dtype'],
  4156. 'value': None}
  4157. return out
  4158. class Identity(PrimitiveWithInfer):
  4159. """
  4160. Returns a Tensor with the same shape and contents as input.
  4161. Inputs:
  4162. - **x** (Tensor) - The shape of tensor is :math:`(x_1, x_2, ..., x_R)`.
  4163. Outputs:
  4164. Tensor, the shape of tensor is the same as `input_x`, :math:`(x_1, x_2, ..., x_R)`.
  4165. Raises:
  4166. TypeError: If `x` is not a Tensor.
  4167. Supported Platforms:
  4168. ``Ascend``
  4169. Examples:
  4170. >>> x = Tensor(np.array([1, 2, 3, 4]), mindspore.int64)
  4171. >>> output = ops.Identity()(x)
  4172. >>> print(output)
  4173. [1 2 3 4]
  4174. """
  4175. # Side effect is identity with input.
  4176. side_effect_propagate = 1
  4177. @prim_attr_register
  4178. def __init__(self):
  4179. """Initialize identity"""
  4180. self.add_prim_attr('side_effect_propagate', 1)
  4181. def __infer__(self, x):
  4182. validator.check_subclass("x", x['dtype'], mstype.tensor, self.name)
  4183. validator.check_tensor_dtype_valid('x', x['dtype'], mstype.number_type + (mstype.bool_,), self.name)
  4184. out = {'shape': x['shape'],
  4185. 'dtype': x['dtype'],
  4186. 'value': None}
  4187. return out
  4188. class Range(PrimitiveWithCheck):
  4189. r"""
  4190. Creates a sequence of numbers that begins at `start` and extends by increments of
  4191. `delta` up to but not including `limit`.
  4192. The types of all 3 inputs must be the same. The type of the resulting tensor is
  4193. the same as the type of the inputs.
  4194. Args:
  4195. maxlen (int): Memory that can fit `maxlen` many elements
  4196. will be allocated for the output. Optional, must be positive, defaults to 1000000.
  4197. If the output has more than `maxlen` elements, a runtime error
  4198. will occur.
  4199. Inputs:
  4200. - **start** (Tensor) - A scalar Tensor. The first number in the sequence. Must have
  4201. type: int32 or float32
  4202. - **limit** (Tensor) - A scalar Tensor. Upper limit of the sequence, exclusive. Must
  4203. have type: int32 or float32
  4204. - **delta** (Tensor) - A scalar Tensor. Number that increments `start`. Must have
  4205. type: int32 or float32
  4206. Outputs:
  4207. A 1-D Tensor, with the same type as the inputs.
  4208. Examples:
  4209. >>> start = Tensor(0, mstype.int32)
  4210. >>> limit = Tensor(10, mstype.int32)
  4211. >>> delta = Tensor(4, mstype.int32)
  4212. >>> output = ops.Range()(start, limit, delta)
  4213. >>> print(output)
  4214. [0, 4, 8]
  4215. Supported Platforms:
  4216. ``GPU``
  4217. """
  4218. @prim_attr_register
  4219. def __init__(self, maxlen=1000000):
  4220. self.init_prim_io_names(inputs=['start', 'limit', 'delta'], outputs=['output'])
  4221. validator.check_value_type("maxlen", maxlen, [int], self.name)
  4222. validator.check_positive_int(maxlen, "maxlen", self.name)
  4223. self.maxlen = maxlen
  4224. self.add_prim_attr('maxlen', maxlen)
  4225. def check_shape(self, start_shape, limit_shape, delta_shape):
  4226. validator.check("start_shape", len(start_shape), "", 0, Rel.EQ, self.name)
  4227. validator.check("limit_shape", len(limit_shape), "", 0, Rel.EQ, self.name)
  4228. validator.check("delta_shape", len(delta_shape), "", 0, Rel.EQ, self.name)
  4229. def check_dtype(self, start_dtype, limit_dtype, delta_dtype):
  4230. valid_dtypes = [mstype.int32, mstype.float32]
  4231. inputs = {"start": start_dtype, "limit": limit_dtype, "delta": delta_dtype}
  4232. validator.check_tensors_dtypes_same_and_valid(inputs, valid_dtypes, self.name)