Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file owl_view.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278# 1 "src/base/misc/owl_view.ml"(*
* OWL - OCaml Scientific and Engineering Computing
* Copyright (c) 2016-2018 Liang Wang <liang.wang@cl.cam.ac.uk>
*)openOwl_typesmoduleS=Pervasives(* Functor of making a View module of given Ndarray module *)moduleMake(A:Ndarray_Basic)=structtypet={shape:intarray;(* shape of the view *)slice:intarrayarray;(* slice definition projected on original data *)ofstr:intarrayarray;(* [|offset; stride|] array of view projected on original data *)data:A.arr;(* original data object *)dvec:A.arr;(* one-dimensional vector of original data *)}(* calculate (offset, stride) from the [shape] of original data and [slice] *)letcalc_ofstrshapeslice=letdims=Array.lengthshapeinletstrides=Owl_utils.calc_strideshapeinArray.initdims(funi->letoffset=slice.(i).(0)*strides.(i)inletstride=strides.(i)*slice.(i).(2)in[|offset;stride|])letmake_viewshapeslicedata={shape;slice;ofstr=calc_ofstr(A.shapedata)slice;data;dvec=A.reshapedata[|A.numeldata|];}(* check whether two views are equivalent *)letis_same_viewxy=(x.data==y.data)&&(x.slice=y.slice)(* core functions *)(* project slice s1 to to s0 on one dimension *)letproject_slice_dims0s1=letstart_0,_stop_0,stride_0=s0.(0),s0.(1),s0.(2)inletstart_1,stop_1,stride_1=s1.(0),s1.(1),s1.(2)inletstart_2=start_0+start_1*stride_0inletstop_2=start_0+stop_1*stride_0inletstride_2=stride_0*stride_1in[|start_2;stop_2;stride_2|](* project slice s1 to s0 on all dimensions *)letproject_slices0s1=Array.map2project_slice_dims0s1(* project the index onto the slice on one dimension *)letproject_index_dimsi=letstart_,_stop_,stride_=s.(0),s.(1),s.(2)instart_+i*stride_(* project indices onto the slice on all dimensions *)letproject_indexsi=Array.map2project_index_dimsiletof_arrx=letshape=A.shapexinlets0=Array.(make(lengthshape))(R_[||])inlets1=Owl_base_slicing.check_slice_definitions0shape|>Array.map(functionR_a->a|_->failwith"owl_view:of_arr")inmake_viewshapes1xletto_arrx=letslice=Array.(map(funa->to_lista)x.slice|>to_list)inA.get_sliceslicex.data(* manipulation functions *)letshapex=x.shapeletnum_dimsx=Array.lengthx.shapeletnth_dimxi=x.shape.(i)letnumelx=Array.fold_left(*)1x.shapeletgetxi=leti'=project_indexx.sliceiinA.getx.datai'letsetxia=leti'=project_indexx.sliceiinA.setx.datai'aletget_sliceaxisx=lets0=Array.of_listaxis|>Array.(mapof_list)inlets1=Array.map(funa->R_a)s0inlets1=Owl_base_slicing.check_slice_definitions1x.shapeinlets2=Array.map(functionR_a->a|_->failwith"owl_view:of_arr")s1inletslice=project_slicex.slices2inletshape=Owl_base_slicing.calc_slice_shapes1inmake_viewshapeslicex.data(* iteration functions *)(* iterate using 1d-index and x.dvec, fast *)letrec_iterifxidim=letoffset=x.ofstr.(dim).(0)inletstride=x.ofstr.(dim).(1)inleti=[|i+offset|]inifdim=num_dimsx-1then(for_j=0tox.shape.(dim)-1dofi(A.getx.dveci);i.(0)<-i.(0)+stride;done)else(for_j=0tox.shape.(dim)-1do_iterifxi.(0)(dim+1);i.(0)<-i.(0)+stride;done)(* iterate using both 1d-index i and its adjusted 1d-index k *)letrec_iteri_adjustedfxikdim=letoffset=x.ofstr.(dim).(0)inletstride=x.ofstr.(dim).(1)inleti=[|i+offset|]inifdim=num_dimsx-1then(for_j=0tox.shape.(dim)-1dof(i,!k)(A.getx.dveci);i.(0)<-i.(0)+stride;k:=!k+1;done)else(for_j=0tox.shape.(dim)-1do_iteri_adjustedfxi.(0)k(dim+1);i.(0)<-i.(0)+stride;done)(* iterate using nd-index and x.data, slow *)letrec_iteri_ndfxidim=ifdim=num_dimsx-1then(forj=0tox.shape.(dim)-1doi.(dim)<-j;fi(getxi)done)else(forj=0tox.shape.(dim)-1doi.(dim)<-j;_iteri_ndfxi(dim+1)done)letrec_iter2fxyi_xi_ydim=letoffset_x=x.ofstr.(dim).(0)inletstride_x=x.ofstr.(dim).(1)inletoffset_y=y.ofstr.(dim).(0)inletstride_y=y.ofstr.(dim).(1)inleti_x=[|i_x+offset_x|]inleti_y=[|i_y+offset_y|]inifdim=num_dimsx-1then(for_j=0tox.shape.(dim)-1dofi_xi_y(A.getx.dveci_x)(A.gety.dveci_y);i_x.(0)<-i_x.(0)+stride_x;i_y.(0)<-i_y.(0)+stride_y;done)else(for_j=0tox.shape.(dim)-1do_iter2fxyi_x.(0)i_y.(0)(dim+1);i_x.(0)<-i_x.(0)+stride_x;i_y.(0)<-i_y.(0)+stride_y;done)letiterfx=_iteri(fun_a->fa)x00letiterifx=_iteri_adjusted(fun(_i,k)a->fka)x0(ref0)0letiteri_ndfx=_iteri_ndfx(Array.make(num_dimsx)0)0letmapfx=_iteri(funia->A.setx.dveci(fa))x00letmapifx=_iteri_adjusted(fun(i,k)a->A.setx.dveci(fka))x0(ref0)0letmapi_ndfx=iteri_nd(funia->setxi(fia))xlet_fold?_axis_f_x=()letiter2fxy=assert(x.shape=y.shape);ifis_same_viewxythen_iteri(fun_a->faa)x00else_iter2(fun__ab->fab)xy000letmap2fxy=assert(x.shape=y.shape);ifis_same_viewxythen_iteri(funia->A.setx.dveci(faa))x00else_iter2(fun_ijab->A.sety.dvecj(fab))xy000letset_sliceaxisxy=letx=get_sliceaxisxinmap2(funb_->b)yx(* Examination & Comparison *)letequalxy=letr=reftruein(tryiter2(funab->assert(a=b))xywith_exn->r:=false);!rletnot_equalxy=not(equalxy)letexistsfx=letb=reffalseintryiter(funy->if(fy)then(b:=true;failwith"found";))x;!bwithFailure_->!bletnot_existsfx=not(existsfx)letfor_allfx=letgy=not(fy)innot_existsgxend