Skip to content

Commit

Permalink
[ci skip] Adding workarounds for Windows Subsystem for Linux.
Browse files Browse the repository at this point in the history
- Adding mutable global rather than use a closure for `vec_size`.
- Manually granting libraries ability to execute on stack in WSL.

See:

  microsoft/WSL#286
  https://stackoverflow.com/q/39136040/1068170
  microsoft/WSL#916
  https://gist.github.com/dhermes/f448415b9160b785f503a7361fe40d51
  microsoft/WSL#2546
  • Loading branch information
dhermes committed Oct 9, 2017
1 parent 8538af4 commit 8fe1fdb
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 18 deletions.
31 changes: 31 additions & 0 deletions setup_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@

import collections
import distutils.ccompiler
import glob
import os
import platform
import shutil
import subprocess
import sys
Expand Down Expand Up @@ -525,6 +527,12 @@ def cleanup(self):
else:
self.CLEANUP()

if is_wsl():
so_glob = os.path.join(self.build_lib, 'bezier', '*.so')
for filename in glob.glob(so_glob):
cmd = ('execstack', '-c', filename)
subprocess.check_call(cmd)

def run(self):
self.set_f90_compiler()
self.start_journaling()
Expand All @@ -536,3 +544,26 @@ def run(self):
self.cleanup()

return result


def is_wsl():
"""Check if currently running in Windows Subsystem for Linux.
WSL will manifest as Linux, but the version information for the
Linux distribution will contain Microsoft:
$ uname --kernel-release
4.4.0-43-Microsoft
$ uname --kernel-version
#1-Microsoft Wed Dec 31 14:42:53 PST 2014
Returns:
bool: Indicating if running on WSL.
"""
if sys.platform in ('linux', 'linux2'):
return (
'microsoft' in platform.release().lower() or
'microsoft' in platform.version().lower()
)
else:
return False
42 changes: 24 additions & 18 deletions src/bezier/curve.f90
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ module curve
LocateCandidate, MAX_LOCATE_SUBDIVISIONS, LOCATE_STD_CAP, &
SQRT_PREC, REDUCE_THRESHOLD, scalar_func, dqagse, &
specialize_curve_generic, specialize_curve_quadratic, &
subdivide_nodes_generic, split_candidate, projection_error, can_reduce
subdivide_nodes_generic, split_candidate, projection_error, &
can_reduce, VEC_SIZE_FIRST_DERIV, vec_size
public &
CurveData, LOCATE_MISS, LOCATE_INVALID, evaluate_curve_barycentric, &
evaluate_multi, specialize_curve, evaluate_hodograph, subdivide_nodes, &
Expand Down Expand Up @@ -55,6 +56,8 @@ module curve
real(c_double), parameter :: LOCATE_MISS = -1
real(c_double), parameter :: LOCATE_INVALID = -2

real(c_double), allocatable :: VEC_SIZE_FIRST_DERIV(:, :)

! Interface blocks for QUADPACK:dqagse
abstract interface
! f: real(c_double) --> real(c_double)
Expand Down Expand Up @@ -744,7 +747,6 @@ subroutine compute_length( &
real(c_double), intent(out) :: length
integer(c_int), intent(out) :: error_val
! Variables outside of signature.
real(c_double) :: first_deriv(num_nodes - 1, dimension_)
real(c_double) :: abserr
integer(c_int) :: neval
real(c_double) :: alist(50)
Expand All @@ -757,9 +759,9 @@ subroutine compute_length( &
! NOTE: We somewhat replicate code in ``evaluate_hodograph()``
! here. This is so we don't re-compute the nodes for the first
! derivative every time it is evaluated.
first_deriv = (num_nodes - 1) * (nodes(2:, :) - nodes(:num_nodes - 1, :))
VEC_SIZE_FIRST_DERIV = (num_nodes - 1) * (nodes(2:, :) - nodes(:num_nodes - 1, :))
if (num_nodes == 2) then
length = norm2(first_deriv)
length = norm2(VEC_SIZE_FIRST_DERIV)
error_val = 0
return
end if
Expand All @@ -769,23 +771,27 @@ subroutine compute_length( &
abserr, neval, error_val, alist, blist, rlist, &
elist, iord, last)

contains
end subroutine compute_length

! Define a closure that evaluates ||B'(s)||_2 where ``s``
! is the argument and ``B'(s)`` is parameterized by ``first_deriv``.
real(c_double) function vec_size(s_val) result(norm_)
real(c_double), intent(in) :: s_val
! Variables outside of signature.
real(c_double) :: evaluated(1, dimension_)
! NOTE: This is mean to **ACT** as a closure.
! Evaluates ||B'(s)||_2 where ``s`` is the argument and ``B'(s)`` is
! parameterized by ``VEC_SIZE_FIRST_DERIV``.
real(c_double) function vec_size(s_val) result(norm_)
real(c_double), intent(in) :: s_val
! Variables outside of signature.
real(c_double), allocatable :: evaluated(:, :)
integer(c_int) :: num_nodes, dimension_

! ``evaluate_multi`` takes degree, which is one less than the number
! of nodes, so our derivative is one less than that.
call evaluate_multi( &
num_nodes - 1, dimension_, first_deriv, 1, [s_val], evaluated)
norm_ = norm2(evaluated)
num_nodes = size(VEC_SIZE_FIRST_DERIV, 1)
dimension_ = size(VEC_SIZE_FIRST_DERIV, 2)
allocate(evaluated(1, dimension_))

end function vec_size
! ``evaluate_multi`` takes degree, which is one less than the number
! of nodes, so our derivative is one less than that.
call evaluate_multi( &
num_nodes, dimension_, VEC_SIZE_FIRST_DERIV, 1, [s_val], evaluated)
norm_ = norm2(evaluated)

end subroutine compute_length
end function vec_size

end module curve

0 comments on commit 8fe1fdb

Please sign in to comment.