(***********************************************************************) (* *) (* Applied Type System *) (* *) (* Hongwei Xi *) (* *) (***********************************************************************) (* ** ATS - Unleashing the Potential of Types! ** Copyright (C) 2002-2010 Hongwei Xi, Boston University ** All rights reserved ** ** ATS is free software; you can redistribute it and/or modify it under ** the terms of the GNU General Public License as published by the Free ** Software Foundation; either version 2.1, or (at your option) any later ** version. ** ** ATS is distributed in the hope that it will be useful, but WITHOUT ANY ** WARRANTY; without even the implied warranty of MERCHANTABILITY or ** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ** for more details. ** ** You should have received a copy of the GNU General Public License ** along with ATS; see the file COPYING. If not, write to the Free ** Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA ** 02110-1301, USA. *) (* ****** ****** *) (* ** ** Fortran matrices: column-major representation ** ** Contributed by Hongwei Xi (hwxi AT cs DOT bu DOT edu) ** Contributed by Shivkumar Chandrasekaran (shiv AT ece DOT ucsb DOT edu) ** ** Time: Summer, 2009 ** *) (* ****** ****** *) // // License: LGPL 3.0 (available at http://www.gnu.org/licenses/lgpl.txt) // (* ****** ****** *) #define ATS_DYNLOADFLAG 0 // no need for dynamic loading (* ****** ****** *) staload "libats/SATS/genarrays.sats" staload _(*anonymous*) = "libats/DATS/genarrays.dats" (* ****** ****** *) staload "libats/SATS/fmatrix.sats" (* ****** ****** *) implement{a} fmatrix_ptr_alloc (m, n) = let val (pf_mn | mn) = mul2_size1_size1 (m, n) prval () = mul_nat_nat_nat (pf_mn) val (pfgc, pfarr | p_arr) = array_ptr_alloc_tsz {a} (mn, sizeof) prval pf_fmat = fmatrix_v_of_array_v (pf_mn, pfarr) in (pfgc, pf_mn, pf_fmat | p_arr) end // end of [fmatrix_ptr_alloc] (* ****** ****** *) implement fmatrix_ptr_free {a} (pfgc, pf_mn, pf_fmat | p_fmat) = let prval (pf2_mn, pfarr) = array_v_of_fmatrix_v (pf_fmat) prval () = mul_isfun (pf2_mn, pf_mn) val () = array_ptr_free {a?} (pfgc, pfarr | p_fmat) in // nothing end // end of [fmatrix_ptr_free] (* ****** ****** *) implement{a} fmatrix_ptr_allocfree (m, n) = let val (pf_mn | mn) = mul2_size1_size1 (m, n) prval () = mul_nat_nat_nat (pf_mn) val [l:addr] ( pfgc, pfarr | p_arr ) = array_ptr_alloc_tsz {a} (mn, sizeof) prval pf_fmat = fmatrix_v_of_array_v (pf_mn, pfarr) in #[l | ( pf_fmat | p_arr , lam (pf_fmat | p_arr) = let prval (pf2_mn, pfarr) = array_v_of_fmatrix_v (pf_fmat) prval () = mul_isfun (pf2_mn, pf_mn) in array_ptr_free {a?} (pfgc, pfarr | p_arr) end ) ] end // end of [fmatrix_ptr_allocfree] (* ****** ****** *) implement{a} fmatrix_ptr_initialize_elt (base, m, n, x) = () where { prval pf_mat = view@ base prval (pf_mn1, pfarr) = array_v_of_fmatrix_v (pf_mat) val (pf_mn2 | mn) = mul2_size1_size1 (m, n) prval () = mul_nat_nat_nat (pf_mn2) prval () = mul_isfun (pf_mn1, pf_mn2) var x: a = x val () = array_ptr_initialize_elt_tsz {a} (base, mn, x, sizeof) prval () = view@ base := fmatrix_v_of_array_v (pf_mn1, pfarr) } // end of [fmatrix_ptr_initialize] (* ****** ****** *) // // HX: initialization is done column by colmun // implement{a} // worth it??? fmatrix_ptr_initialize_vclo {v} {m,n} (pf | base, m, n, f) = () where { prval pf_mat = view@ base prval (pf1_mn, pfarr) = array_v_of_fmatrix_v (pf_mat) val [mn:int] (pf2_mn | mn) = mul2_size1_size1 (m, n) prval () = mul_nat_nat_nat (pf2_mn) prval () = mul_isfun (pf1_mn, pf2_mn) // typedef clo_t = (!v | &(a?) >> a, sizeLt m, sizeLt n) - void // fun loop_one {mi:nat | mi <= m} {l:addr} .. ( pfarr: !array_v (a?, mi, l) >> array_v (a, mi, l) , pf: !v | p: ptr l, f: &clo_t, mi: size_t mi, j: sizeLt n ) : void = if mi > 0 then let prval (pf1_elt, pf2_arr) = array_v_uncons {a?} (pfarr) val () = f (pf | !p, m - mi, j) val () = loop_one (pf2_arr, pf | p+sizeof, f, mi - 1, j) prval () = pfarr := array_v_cons {a} (pf1_elt, pf2_arr) in // nothing end else let prval () = array_v_unnil {a?} (pfarr) prval () = pfarr := array_v_nil {a} () in // nothing end // end of [loop_one] // fun loop_all {nj:nat | nj <= n} {p:int} {l:addr} .. ( pf_mul: MUL (nj, m, p) , pfarr: !array_v (a?, p, l) >> array_v (a, p, l) , pf: !v | p: ptr l , f: &clo_t , nj: size_t nj ) : void = if nj > 0 then let prval () = mul_nat_nat_nat (pf_mul) prval pf1_mul = mul_add_const {~1} (pf_mul) prval () = mul_nat_nat_nat (pf1_mul) val (pfmul, pf1_arr, pf2_arr | p1) = array_ptr_split_tsz {a?} (pfarr | p, m, sizeof) val () = loop_one (pf1_arr, pf | p, f, m, n-nj) val () = loop_all (pf1_mul, pf2_arr, pf | p1, f, nj-1) prval () = pfarr := array_v_unsplit {a} (pfmul, pf1_arr, pf2_arr) // end of [prval] in // nothing end else let prval MULbas () = pf_mul prval () = array_v_unnil {a?} (pfarr) prval () = pfarr := array_v_nil {a} () in // nothing end // end of [loop_all] // prval pf_nm = mul_commute (pf1_mn) val () = loop_all (pf_nm, pfarr, pf | &base, f, n) // prval () = view@ base := fmatrix_v_of_array_v (pf1_mn, pfarr) } // end of [fmatrix_ptr_initialize_vclo] (* ****** ****** *) local // // HX: implemented in [libats/CATS/fmatrix.cats] // extern fun fmatrix_ptr_takeout_tsz {a:viewt@ype} {m,n:int} {i,j:nat | i < m; j < n} {l0:addr} ( pf_mat: fmatrix_v (a, m, n, l0) | base: ptr l0, m: size_t m, i: size_t i, j: size_t j, tsz: sizeof_t a ) :<> [l:addr] ( a @ l , a @ l - fmatrix_v (a, m, n, l0) | ptr l ) = "atslib_fmatrix_ptr_takeout_tsz" // end of [fmatrix_ptr_takeout_tsz] in // in of [local] implement{a} fmatrix_ptr_takeout (pf_mat | base, m, i, j) = begin fmatrix_ptr_takeout_tsz {a} (pf_mat | base, m, i, j, sizeof) end // end of [fmatrix_ptr_takeout] implement{a} fmatrix_ptr_get_elt_at (base, m, i, j) = x where { prval pf_mat = view@ base val (pf_elt, fpf_mat | p_elt) = fmatrix_ptr_takeout_tsz {a} (pf_mat | &base, m, i, j, sizeof) // end of [val] val x = !p_elt prval () = view@ base := fpf_mat (pf_elt) } // end of [fmatrix_ptr_get_elt_at] implement{a} fmatrix_ptr_set_elt_at (base, m, i, j, x) = () where { prval pf_mat = view@ base val (pf_elt, fpf_mat | p_elt) = fmatrix_ptr_takeout_tsz {a} (pf_mat | &base, m, i, j, sizeof) // end of [val] val () = !p_elt := x prval () = view@ base := fpf_mat (pf_elt) } // end of [fmatrix_ptr_set_elt_at] end // end of [local] (* ****** ****** *) implement{a} fmatrix_ptr_copy {m,n} (A, B, m, n) = let val [mn:int] (pf_mn | mn) = mul2_size1_size1 (m, n) prval () = mul_nat_nat_nat (pf_mn) prval (pf2_mn, pfA_arr) = array_v_of_fmatrix_v {a} {m,n} (view@ A) prval (pf3_mn, pfB_arr) = array_v_of_fmatrix_v {a?} {m,n} (view@ B) prval () = mul_isfun (pf_mn, pf2_mn) prval () = mul_isfun (pf_mn, pf3_mn) stavar lA: addr and lB: addr prval pfA_arr = pfA_arr: array_v (a, mn, lA) prval pfB_arr = pfB_arr: array_v (a?, mn, lB) val () = array_ptr_copy_tsz {a} {mn} (A, B, mn, sizeof) prval () = view@ A := fmatrix_v_of_array_v {a} {m,n} {mn} (pf2_mn, pfA_arr) prval () = view@ B := fmatrix_v_of_array_v {a} {m,n} {mn} (pf3_mn, pfB_arr) in // nothing end // end of [fmatrix_ptr_copy] (* ****** ****** *) // // HX: loop proceeds column by column // implement fmatrix_ptr_foreach_funenv_tsz {a} {v} {vt} {ord} {m,n} (pf | M, f, ord, m, n, tsz, env) = if m > 0 then let prval (pf_mat, fpf) = GEMAT_v_of_fmatrix_v {a} (view@ M) val () = GEMAT_ptr_foreach_funenv_tsz (pf | ORDERcol, M, f, ord, m, n, m, tsz, env) prval () = view@ M := fpf (pf_mat) in // nothing end (* end of [fmatrix_ptr_foreach_funenv_tsz] *) (* ****** ****** *) implement{a} fmatrix_ptr_foreach_fun (M, f, ord, m, n) = let val f = coerce (f) where { extern castfn coerce (f: (&a) -<> void) :<> (!unit_v | &a, !ptr) -<> void } // end of [where] prval pfu = unit_v () val () = fmatrix_ptr_foreach_funenv_tsz {a} {unit_v} {ptr} (pfu | M, f, ord, m, n, sizeof, null) prval unit_v () = pfu in // nothing end // end of [fmatrix_ptr_foreach_fun] (* ****** ****** *) implement{a} fmatrix_ptr_foreach_vclo {v} (pf_v | M, f, ord, m, n) = let stavar l_f: addr val p_f: ptr l_f = &f typedef clo_t = (!v | &a) - void viewdef V = @(v, clo_t @ l_f) fn app (pf: !V | x: &a, p_f: !ptr l_f):<> void = let prval (pf1, pf2) = pf in !p_f (pf1 | x); pf := @(pf1, pf2) end // end of [app] prval pf = (pf_v, view@ f) val () = fmatrix_ptr_foreach_funenv_tsz {a} {V} {ptr l_f} (pf | M, app, ord, m, n, sizeof, p_f) prval (pf1, pf2) = pf prval () = (pf_v := pf1; view@ f := pf2) in // empty end // end of [fmatrix_ptr_foreach_vclo] (* ****** ****** *) // // HX: loop proceeds column by column // implement fmatrix_ptr_iforeach_funenv_tsz {a} {v} {vt} {ord} {m,n} (pf | M, f, ord, m, n, tsz, env) = if m > 0 then let prval (pf_mat, fpf) = GEMAT_v_of_fmatrix_v {a} (view@ M) val () = GEMAT_ptr_iforeach_funenv_tsz (pf | ORDERcol, M, f, ord, m, n, m, tsz, env) prval () = view@ M := fpf (pf_mat) in // nothing end (* end of [fmatrix_ptr_iforeach_funenv_tsz] *) (* ****** ****** *) implement{a} fmatrix_ptr_iforeach_fun {ord} {m,n} (M, f, ord, m, n) = if m > 0 then let prval (pf_mat, fpf) = GEMAT_v_of_fmatrix_v {a} (view@ M) val () = GEMAT_ptr_iforeach_fun (ORDERcol, M, f, ord, m, n, m) prval () = view@ M := fpf (pf_mat) in // nothing end (* end of [fmatrix_ptr_iforeach_fun] *) (* ****** ****** *) implement{a} fmatrix_ptr_iforeach_vclo {v} {ord} {m,n} (pf | M, f, ord, m, n) = if m > 0 then let prval (pf_mat, fpf) = GEMAT_v_of_fmatrix_v {a} (view@ M) val () = GEMAT_ptr_iforeach_vclo (pf | ORDERcol, M, f, ord, m, n, m) prval () = view@ M := fpf (pf_mat) in // nothing end (* end of [fmatrix_ptr_iforeach_vclo] *) (* ****** ****** *) (* end of [fmatrix.dats] *)