diff --git a/Configure.nqp b/Configure.nqp deleted file mode 100644 index c41574a..0000000 --- a/Configure.nqp +++ /dev/null @@ -1,55 +0,0 @@ -# Purpose: Use Parrot's config info to configure our Makefile. -# -# Usage: -# parrot_nqp Configure.nqp -# TODO: The PARROTREVISON file contains a minimum svn revision of Parrot that is -# needed to make this build. Check that we meet that minimum requirement. - -our @ARGS; -our %VM; -our $OS; - -MAIN(); - -sub MAIN () { - # Wave to the friendly users - say("Hello, I'm Configure. My job is to poke and prod your system"); - say("to figure out how to build parrot-linear-algebra.\n"); - - # Load Parrot config and glue functions - pir::load_bytecode('PGE.pbc'); - pir::load_bytecode('config/config-helpers.pir'); - - # Slurp in the unconfigured Makefile text - my $unconfigured := slurp(@ARGS[0] || 'config/Makefile.in'); - - # Set up our custom @foo@ markers. - if ($OS ne 'openbsd') { - %VM{'linkblas'} := '-lblas'; - } - - # Replace all of the @foo@ markers - my $replaced := subst($unconfigured, rx('\@\@'), replacement); - - # Fix paths on Windows - if ($OS eq 'MSWin32') { - $replaced := subst($replaced, rx('/'), '\\'); - } - - # Spew out the final makefile - spew(@ARGS[1] || 'Makefile', $replaced); - - # Give the user a hint of next action - say("Configure completed."); - say("You can now type '" ~ %VM ~ "' to build parrot-linear-algebra.\n"); - say("You may also type '" ~ %VM ~ " test' to run the test suite.\n"); - say("Happy Hacking,"); - say("\tThe parrot-linear-algebra Team"); -} - -sub replacement ($match) { - my $key := $match; - my $config := %VM{$key} || ''; - - return $config; -} diff --git a/PARROTREVISION b/PARROTREVISION deleted file mode 100644 index 996b391..0000000 --- a/PARROTREVISION +++ /dev/null @@ -1 +0,0 @@ -44190 \ No newline at end of file diff --git a/README b/README index 771acfc..4ad556f 100644 --- a/README +++ b/README @@ -2,7 +2,7 @@ parrot-linear-algebra A linear algebra library package for the Parrot Virtual Machine -== PROJECT GOALS +== PROJECT GOALS == The goals of the Parrot-Linear-Algebra (PLA) project are to develop a good, high-performance linear algebra toolset for use with the Parrot Virtual @@ -14,42 +14,34 @@ In addition to these core goals, PLA may also provide a series of ancillary tools that are similar in implementation to it's high-performance core utilities. -OLD Project Site: http://code.google.com/p/matrixy -NEW Project Site: http://github.com/Whiteknight/matrixy -Parrot: http://www.parrot.org - -== STATUS +== STATUS == PLA is being actively developed. It has core PMC types that build, a build and installation system, and a growing test suite. PLA currently provides these PMC types: -=over 4 - -=item NumMatrix2D +* NumMatrix2D -A 2-D matrix containing floating point values. + A 2-D matrix containing floating point values. -=item PMCMatrix2D +* PMCMatrix2D -A 2-D matrix containing PMC pointers + A 2-D matrix containing PMC pointers -=item ComplexMatrix2D +* ComplexMatrix2D -A 2-D matrix containing Complex values, optimized to store complex values -directly instead of using an array of Parrot's Complex PMC type. + A 2-D matrix containing Complex values, optimized to store complex values + directly instead of using an array of Parrot's Complex PMC type. -=item CharMatrix2D +* CharMatrix2D -A 2-D character matrix that doubles as an array of strings with fixed-row-length -storage. - -=back + A 2-D character matrix that doubles as an array of strings with + fixed-row-length storage. PLA does not yet offer matrix or tensor types with more than two dimensions. -== DEPENDENCIES +== DEPENDENCIES == PLA has several dependencies. To help manage dependencies, you may want to install Plumage @@ -58,78 +50,78 @@ http://gitorious.org/parrot-plumage This is not a dependency, just a convenience. -Here are a list of dependencies for PLA: +Each PLA release will target different versions of the various dependencies. +See the file RELEASES for information about individual releases and their +dependencies. -=over 4 - -=item Parrot 2.2.0 - -PLA will be built and tested against the 2.2.0 release of Parrot. Get the 2.2.0 -release here: +Here are a list of dependencies for PLA: -https://svn.parrot.org/parrot/tags/RELEASE_2_2_0 +* Parrot 2.2.0 -PLA will not build at all with older releases. PLA will not build with the -long-term supported 2.0.0 release. + PLA is an extension for Parrot and requires Parrot to build and run. + Releases of PLA will target supported releases of Parrot. Supported + releases are typically X.0, X.3, X.6, X.9. Releases for Parrot can be + retrieved from -Starting April 2010 PLA will be tracking Parrot's supported releases which are -made public every 3 months. The 2.3.0 release will be in April 2010, and PLA -will be built and tested against that release until the 2.6.0 release in July, -then the 2.9.0 release in October, and then the 3.0.0 release in January. + http://www.parrot.org -PLA expects a built and installed Parrot. For more information about the -installation process + Development between releases will typically target the latest supported + release, though it may begin to target more recent development releases in + anticipation of the next supported release. -=item CBLAS or ATLAS + PLA expects a built and installed Parrot. For more information about the + installation process -PLA depends on either CBLAS or ATLAS. The BLAS library is written in Fortran, -so C language bindings are all translations of the Fortran interface. -Unfortunately there is not a good, standard way of translating the Fortran -source to C API bindings, so not all libraries that provide a C API for BLAS -will have an interface compatible with PLA. We are working to be more accepting -of small differences in various interfaces, but this work is moving slowly. +* CBLAS or ATLAS -We recommend the ATLAS library for current development and testing work. On -Ubuntu or other Debian-based distros, you can type this incantation to get it -automatically: + PLA depends on either CBLAS or ATLAS. The BLAS library is written in + Fortran, so C language bindings are all translations of the Fortran + interface. Unfortunately there is not a good, standard way of translating + the Fortran source to C API bindings, so not all libraries that provide a + C API for BLAS will have an interface compatible with PLA. We are working + to be more accepting of small differences in various interfaces, but this + work is moving slowly. - sudo apt-get install libatlas3-base - sudo apt-get install libatlas-base-dev + We recommend the ATLAS library for current development and testing work. + On Ubuntu or other Debian-based distros, you can type this incantation to + get it automatically: -On Fedora you can type: + sudo apt-get install libatlas3-base + sudo apt-get install libatlas-base-dev - sudo yum install atlas-devel + On Fedora you can type: -Notice that the default vesions of the atlas library are only generally -optimized. If you are able try to use a platform-specific variant (such -as "-sse2" or "-3dnow") for better performance. See the ATLAS homepage for more -information: + sudo yum install atlas-devel -http://math-atlas.sourceforge.net/ + Notice that the default vesions of the atlas library are only generally + optimized. If you are able try to use a platform-specific variant (such + as "-sse2" or "-3dnow") for better performance. See the ATLAS homepage for + more information: -=item Kakapo Release-10 + http://math-atlas.sourceforge.net/ -Kakapo is a framework library for the NQP language. PLA currently uses Kakapo to -implement it's unit testing suite. You can build and install PLA without Kakapo, -but you will need the framework to run the test suite. You can obtain Kakapo -from it's source code repository on Gitorious, and get documentation from its -project page on Google Code: +* Kakapo -http://gitorious.org/kakapo -http://code.google.com/p/kakapo-parrot/ + Kakapo is a framework library for the NQP language. PLA currently uses + Kakapo to implement it's unit testing suite. You can build and install + PLA without Kakapo, but you will need the framework to run the test suite. + You can obtain Kakapo from it's source code repository on Gitorious, and + get documentation from its project page on Google Code: -=item Other + http://gitorious.org/kakapo + http://code.google.com/p/kakapo-parrot/ -Currently, PLA is only tested to build and work on Linux and other Unix-like -systems with all the aforementioned prerequisites. The setup process pulls -configuration information from your installed version of Parrot, so it will -attempt to use the same compiler with the same compilation options as Parrot -was compiled with. If another compiler absolutely needs to be used, there may -be a way to specify that, but no documentation about the process exists. +* Other -=back + Currently, PLA is only tested to build and work on Linux and other + Unix-like systems with all the aforementioned prerequisites. The setup + process pulls configuration information from your installed version of + Parrot, so it will attempt to use the same compiler with the same + compilation options as Parrot was compiled with. If another compiler + absolutely needs to be used, there may be a way to specify that, but no + documentation about the process exists. -== BUILDING +== BUILDING == To get, build, test, and install Parrot-Linear-Algebra, follow these steps (on Linux): @@ -140,11 +132,11 @@ To get, build, test, and install Parrot-Linear-Algebra, follow these steps parrot setup.pir test parrot setup.pir install -Testing only works if you have Kakapo installed on your system. To install, you -may need root privileges on your system. There is currently no known way to -build or deploy PLA on Windows. +Testing only works if you have Kakapo installed on your system. To install, +you may need root privileges on your system. There is currently no known way +to build or deploy PLA on Windows. -== CREDITS +== CREDITS == Original versions were developed as part of the Matrixy project by Blairuk. Some parts of the test suite were provided by Austin Hastings. diff --git a/RELEASES b/RELEASES new file mode 100644 index 0000000..ee58919 --- /dev/null +++ b/RELEASES @@ -0,0 +1,9 @@ +TBA : Release 0.1 + Parrot Version: 2.3.0 + Kakapo Version: TBA + New Features: + - Initial release + - Add stable types ComplexMatrix2D, NumMatrix2D, PMCMatrix2D + Known Issues: + - CharMatrix2D is incomplete and fails tests + - Very few bindings with BLAS, very little arithmetic support diff --git a/config/Makefile.in b/config/Makefile.in deleted file mode 100644 index 6ae7825..0000000 --- a/config/Makefile.in +++ /dev/null @@ -1,111 +0,0 @@ -INCLUDE_DIR = @includedir@@versiondir@ -PMC_INCLUDE_DIR = @includedir@@versiondir@/pmc -LIB_DIR = @libdir@@versiondir@ -SRC_DIR = @srcdir@@versiondir@ -TOOLS_DIR = @libdir@@versiondir@/tools -INSTALL_DIR = $(LIB_DIR)/dynext - -LOAD_EXT = @load_ext@ -O = @o@ -DUMP = .dump - -PERL = @perl@ -RM_F = @rm_f@ -CP = @cp@ -MV = @mv@ -CAT = @cat@ -PARROT = @bindir@/parrot@exe@ -PBC_TO_EXE = @bindir@/pbc_to_exe$(EXE) -PERL_LIB = $(TOOLS_DIR)/lib -NQP = $(PARROT) $(LIB_DIR)/library/nqp-rx.pbc -PBC_TO_EXE = @bindir@/pbc_to_exe -CFLAGS = -fPIC @ccflags@ - -LD = @ld@ -LD_LOAD_FLAGS = @ld_load_flags@ -LDFLAGS = @ldflags@ @ld_debug@ -LINKARGS = $(LDFLAGS) $(LD_LOAD_FLAGS) @linkblas@ - -PARROT_DYNEXT = $(LIB_DIR)/dynext -PERL6GRAMMAR = $(LIB_DIR)/library/PGE/Perl6Grammar.pbc -PCT = $(LIB_DIR)/PCT.pbc -PMC2C = $(PERL) $(TOOLS_DIR)/build/pmc2c.pl - -GROUP = linalg_group -PMC_DIR = src/pmc -DYNPMC = $(GROUP)$(LOAD_EXT) -DYNEXT_DIR = dynext - -PMC2C_INCLUDES = --include $(PMC_DIR) --include $(SRC_DIR) --include $(SRC_DIR)/pmc - -PMC_SOURCES = \ - $(PMC_DIR)/nummatrix2d.pmc \ - $(PMC_DIR)/pmcmatrix2d.pmc \ - $(PMC_DIR)/charmatrix2d.pmc \ - $(PMC_DIR)/complexmatrix2d.pmc - -all: $(DYNPMC) - -clean: - $(RM_F) src/pmc/*$(O) - $(RM_F) src/pmc/*$(DUMP) - $(RM_F) src/pmc/*.c - $(RM_F) src/pmc/pmc_*.h - $(RM_F) src/pmc/$(GROUP)$(LOAD_EXT) - $(RM_F) $(GROUP).* - $(RM_F) dynext/*$(LOAD_EXT) - -realclean: clean - $(RM_F) t/*.pbc - $(RM_F) Makefile - - - -install: all -#IF(cygwin or hpux): CHMOD 0775 linalg_group$(LOAD_EXT) - $(CP) linalg_group$(LOAD_EXT) $(INSTALL_DIR) - -uninstall: - $(RM_F) $(INSTALL_DIR)/linalg_group$(LOAD_EXT) - -test: t/Glue.pbc all - $(NQP) t/harness t/*.t && $(NQP) t/harness t/pmc/*.t - -t/Glue.pbc: t/Glue.pir - $(PARROT) -o t/Glue.pbc t/Glue.pir - -$(DYNPMC): src/pmc/pla_matrix_types.h $(PMC_SOURCES) - $(PMC2C) --no-lines --dump $(PMC2C_INCLUDES) $(PMC_SOURCES) - $(PMC2C) --no-lines --c $(PMC2C_INCLUDES) $(PMC_SOURCES) - $(PMC2C) --no-lines --library $(GROUP) --c $(PMC_SOURCES) - $(CC) -c @cc_o_out@$(GROUP)$(O) -I$(PMC_DIR) -I$(INCLUDE_DIR) -I$(PMC_INCLUDE_DIR) $(CFLAGS) $(GROUP).c - cd $(PMC_DIR) && $(CC) -c -I$(INCLUDE_DIR) -I$(PMC_INCLUDE_DIR) $(CFLAGS) *.c - $(LD) @ld_out@$(DYNPMC) $(GROUP)$(O) src/pmc/*$(O) $(LINKARGS) - $(MV) $(DYNPMC) . - -# This is a listing of all targets, that are meant to be called by users -help: - @echo "" - @echo "Following targets are available for the user:" - @echo "" - @echo " all: This is the default." - @echo "Testing:" - @echo " test: Run the test suite." - @echo "" - @echo "Cleaning:" - @echo " clean: Basic cleaning up." - @echo " realclean: Removes also files generated by 'Configure.pl'" - @echo "" - @echo "Installation:" - @echo " install: Install the pmcs to Parrot's install dir" - @echo " uninstall: Remove an existing installation" - @echo "" - @echo "Misc:" - @echo " help: Print this help message." - @echo "" - -# Local variables: -# mode: makefile -# End: -# vim: ft=make: - diff --git a/config/config-helpers.pir b/config/config-helpers.pir deleted file mode 100644 index ddf8145..0000000 --- a/config/config-helpers.pir +++ /dev/null @@ -1,302 +0,0 @@ -=head1 NAME - -Glue.pir - Rakudo "glue" builtins (functions/globals) converted for NQP - - -=head1 SYNOPSIS - - # Load this library - load_bytecode('src/lib/Glue.pbc'); - - # I/O - $contents := slurp($filename); - spew( $filename, $contents); - append($filename, $contents); - - # Regular expressions - $regex_object := rx($regex_source); - @matches := all_matches($regex, $text); - $edited := subst($original, $regex, $replacement); - - # Global variables; - our $PROGRAM_NAME; - our @ARGS; - our %ENV; - our %VM; - our $OS; - our $OSVER; - - -=cut - -.namespace [] - -.include 'interpinfo.pasm' -.include 'sysinfo.pasm' -.include 'iglobals.pasm' - - -=head1 DESCRIPTION - -=head2 Functions - -=over 4 - -=item $contents := slurp($filename) - -Read the C<$contents> of a file as a single string. - -=cut - -.sub 'slurp' - .param string filename - .local string contents - - $P0 = open filename, 'r' - contents = $P0.'readall'() - close $P0 - .return(contents) -.end - - -=item spew($filename, $contents) - -Write the string C<$contents> to a file. - -=cut - -.sub 'spew' - .param string filename - .param string contents - - $P0 = open filename, 'w' - $P0.'print'(contents) - close $P0 -.end - - -=item append($filename, $contents) - -Append the string C<$contents> to a file. - -=cut - -.sub 'append' - .param string filename - .param string contents - - $P0 = open filename, 'a' - $P0.'print'(contents) - close $P0 -.end - - -=item $regex_object := rx($regex_source) - -Compile C<$regex_source> (a string representing the source code form of a -Perl 6 Regex) into a C<$regex_object>, suitable for using in C and -C. - -=cut - -.sub 'rx' - .param string source - - .local pmc p6regex, object - p6regex = compreg 'PGE::Perl6Regex' - object = p6regex(source) - - .return(object) -.end - -=item @matches := all_matches($regex, $text) - -Find all matches (C<:g> style, not C<:exhaustive>) for C<$regex> in the -C<$text>. The C<$regex> must be a regex object returned by C. - -=cut - -.sub 'all_matches' - .param pmc regex - .param string text - - # Find all matches in the original string - .local pmc matches, match - matches = root_new ['parrot';'ResizablePMCArray'] - match = regex(text) - unless match goto done_matching - - match_loop: - push matches, match - - $I0 = match.'to'() - match = regex(match, 'continue' => $I0) - - unless match goto done_matching - goto match_loop - done_matching: - - .return(matches) -.end - - -=item $edited := subst($original, $regex, $replacement) - -Substitute all matches of the C<$regex> in the C<$original> string with the -C<$replacement>, and return the edited string. The C<$regex> must be a regex -object returned by the C function. - -The C<$replacement> may be either a simple string or a sub that will be called -with each match object in turn, and must return the proper replacement string -for that match. - -=cut - -.sub 'subst' - .param string original - .param pmc regex - .param pmc replacement - - # Find all matches in the original string - .local pmc matches - matches = all_matches(regex, original) - - # Do the substitutions on a clone of the original string - .local string edited - edited = clone original - - # Now replace all the matched substrings - .local pmc match - .local int offset - offset = 0 - replace_loop: - unless matches goto done_replacing - match = shift matches - - # Handle either string or sub replacement - .local string replace_string - $I0 = isa replacement, 'Sub' - if $I0 goto call_replacement_sub - replace_string = replacement - goto have_replace_string - call_replacement_sub: - replace_string = replacement(match) - have_replace_string: - - # Perform the replacement - $I0 = match.'from'() - $I1 = match.'to'() - $I2 = $I1 - $I0 - $I0 += offset - substr edited, $I0, $I2, replace_string - $I3 = length replace_string - $I3 -= $I2 - offset += $I3 - goto replace_loop - done_replacing: - - .return(edited) -.end - -=item $joined := join($delimiter, @strings) - -Join C<@strings> together with the specified C<$delimiter>. - -=cut - -.sub 'join' - .param string delim - .param pmc strings - - .local string joined - joined = join delim, strings - - .return (joined) -.end - -=item @pieces := split($delimiter, $original) - -Split the C<$original> string with the specified C<$delimiter>, which is not -included in the resulting C<@pieces>. - -=cut - -.sub 'split' - .param string delim - .param string original - - .local pmc pieces - pieces = split delim, original - - .return (pieces) -.end - -=back - -=head2 Global Variables - -=over 4 - -=item $PROGRAM_NAME - -Name of running program (argv[0] in C) - -=item @ARGS - -Program's command line arguments (including options, which are NOT parsed) - -=item %VM - -Parrot configuration - -=item %ENV - -Process-wide environment variables - -=item $OS - -Operating system generic name - -=item $OSVER - -Operating system version - -=back - -=cut - -.sub 'onload' :anon :load :init - load_bytecode 'config.pbc' - $P0 = getinterp - $P1 = $P0[.IGLOBALS_CONFIG_HASH] - $P2 = new ['Hash'] - $P2['config'] = $P1 - set_hll_global '%VM', $P2 - - $P1 = $P0[.IGLOBALS_ARGV_LIST] - if $P1 goto have_args - unshift $P1, '' - have_args: - $S0 = shift $P1 - $P2 = box $S0 - set_hll_global '$PROGRAM_NAME', $P2 - set_hll_global '@ARGS', $P1 - - $P0 = root_new ['parrot';'Env'] - set_hll_global '%ENV', $P0 - - $S0 = sysinfo .SYSINFO_PARROT_OS - $P0 = box $S0 - set_hll_global '$OS', $P0 - - $S0 = sysinfo .SYSINFO_PARROT_OS_VERSION - $P0 = box $S0 - set_hll_global '$OSVER', $P0 -.end - - -# Local Variables: -# mode: pir -# fill-column: 100 -# End: -# vim: expandtab shiftwidth=4 ft=pir: diff --git a/ports/plumage/parrot-linear-algebra.json b/ports/plumage/parrot-linear-algebra.json new file mode 100644 index 0000000..9ae74af --- /dev/null +++ b/ports/plumage/parrot-linear-algebra.json @@ -0,0 +1,64 @@ +{ + "meta-spec" : { + "version" : 1, + "uri" : "https://trac.parrot.org/parrot/wiki/ModuleEcosystem" + }, + "general" : { + "name" : "parrot-linear-algebra", + "abstract" : "Linear Algebra Package for Parrot VM", + "authority": "http://github.com/Whiteknight", + "version" : "0.1", + "license" : { + "type" : "Artistic License 2.0", + "uri" : "http://www.perlfoundation.org/artistic_license_2_0" + }, + "copyright_holder" : "PLA Contributors", + "generated_by" : "distutils", + "keywords" : ["matrix", "linear", "algebra", "gsl", "atlas", "blas", "cblas"], + "description" : "Linear Algebra Package for Parrot VM." + }, + "instructions" : { + "fetch" : { + "type" : "repository" + }, + "update" : { + "type" : "parrot_setup" + }, + "build" : { + "type" : "parrot_setup" + }, + "test" : { + "type" : "parrot_setup" + }, + "smoke" : { + "type" : "parrot_setup" + }, + "install" : { + "type" : "parrot_setup" + }, + "uninstall": { + "type" : "parrot_setup" + }, + "clean" : { + "type" : "parrot_setup" + } + }, + "dependency-info" : { + "provides" : ["parrot-linear-algebra"], + "requires" : { + "fetch" : ["git"], + "build" : [], + "test" : [], + "install" : [], + "runtime" : [] + } + }, + "resources" : { + "repository" : { + "type" : "git", + "checkout_uri": "git://github.com/Whiteknight/parrot-linear-algebra.git", + "browser_uri" : "http://github.com/Whiteknight/parrot-linear-algebra", + "project_uri" : "http://github.com/Whiteknight/parrot-linear-algebra" + } + } +} diff --git a/setup.pir b/setup.pir index 5a0b16c..6c3cb11 100755 --- a/setup.pir +++ b/setup.pir @@ -33,10 +33,11 @@ See F. $P0['keywords'] = $P1 $P0['license_type'] = 'Artistic License 2.0' $P0['license_uri'] = 'http://www.perlfoundation.org/artistic_license_2_0' - $P0['copyright_holder'] = 'Blair Sutton and Andrew Whitworth' + $P0['copyright_holder'] = 'PLA Contributors' $P0['checkout_uri'] = 'git://github.com/Whiteknight/parrot-linear-algebra.git' $P0['browser_uri'] = 'http://github.com/Whiteknight/parrot-linear-algebra' $P0['project_uri'] = 'http://github.com/Whiteknight/parrot-linear-algebra' + $P0['version'] = "0.1" # build $I0 = elements args @@ -60,14 +61,21 @@ SOURCES $P2['linalg_group'] = $P3 $P0['dynpmc'] = $P2 - - # test + $S0 = args[0] + if $S0 != "test" goto no_test $S0 = get_nqp() - $P0['harness_exec'] = $S0 - $P0['harness_files'] = '' + $S0 = $S0 . " t/harness" + $I0 = spawnw $S0 + exit $I0 + # test + #$S0 = get_nqp() + #$S0 = $S0 . " t/harness" + #$P0['test_exec'] = $S0 + no_test: + # dist - $P5 = glob('src/pmc/pla_matrix_types.h src/*.pir src/*.m examples/*.pir tools/nci/*.pl') + $P5 = glob('src/pmc/pla_matrix_types.h src/*.pir src/*.m examples/*.pir') $P0['manifest_includes'] = $P5 .tailcall setup(args :flat, $P0 :flat :named) diff --git a/src/fortran_helpers.pir b/src/fortran_helpers.pir deleted file mode 100644 index 6792723..0000000 --- a/src/fortran_helpers.pir +++ /dev/null @@ -1,445 +0,0 @@ -=head1 DESCRIPTION - -These utility functions are for transfering -Matrixy row-major ResizablePMCArrays to the -Fortran/Clapack column-major ManagedStructs and back. - -Tested manually using the following code: - - - Matrixy (.M): - ============ - A = [1, 2, 3, 4; 5, 6, 7, 8; 9, 10, 11, 12; 13, 14, 15, 16]; - B = test(A); - print A; - print B; - - - PIR (.pir): - =========== - .sub 'test' - A1 = '!matrixy_to_fortran_array'(A) - A = '!clapack_to_fortran_array'(A1, 4, 4) - .return(A) - .sub - -Running the M file above should print two identical arrays. These will -be incorporated into a unit test once inline PIR is complete. - -=cut - -.namespace ['_Matrixy';'builtins'] - -.include 'datatypes.pasm' - -.sub '_test_fortran_array_conversions' - .param int nargout - .param int nargin - .param pmc A - .param string type :optional - .param int has_type :opt_flag - - .local int rows, cols - .local pmc B, C - rows = 'rows'(1,1,A) - cols = 'columns'(1,1,A) - - if has_type goto call_with_type - B = '!matrixy_to_fortran_array'(A) - C = '!fortran_to_matrixy_array'(B, rows, cols) - goto compare_main - - call_with_type: - B = '!matrixy_to_fortran_array'(A, type) - C = '!fortran_to_matrixy_array'(B, rows, cols, type) - - compare_main: - - # if A is scalar then it has been coerced into an array - # so just check that A = C[0;0] - $S0 = typeof A - if $S0 == "ResizablePMCArray" goto compare_array - $P0 = A - $P1 = C[0;0] - if $P0 != $P1 goto failure - goto success - - compare_array: - .local int i, j - i = -1 - next_i: - i = i + 1 - unless i < rows goto success - j = -1 - next_j: - j = j + 1 - unless j < cols goto next_i - $P0 = A[i;j] - $P1 = C[i;j] - if $P0 != $P1 goto failure - goto next_j - - success: - .return(1) - - failure: - .return(0) - -.end - -.namespace [] - -.macro say_indexes(i, j, n, v) - $P100 = new 'ResizablePMCArray' - push $P100, .i - push $P100, .j - push $P100, .n - push $P100, .v - $S100 = sprintf "(%s,%s) -> %s = %s", $P100 - say $S100 -.endm - -.sub '!matrixy_to_fortran_array' - .param pmc a - .param string type :optional - .param int has_type :opt_flag - - .local int rows, cols - - # if we have a scalar, wrap it as an array - $S0 = typeof a - if $S0 == "ResizablePMCArray" goto have_array - $P0 = new 'ResizablePMCArray' - $P1 = new 'ResizablePMCArray' - push $P1, a - push $P0, $P1 - rows = 1 - cols = 1 - a = $P0 - goto set_type - - have_array: - $P0 = '!get_matrix_sizes'(a) - rows = $P0[0] - cols = $P0[1] - - set_type: - unless has_type goto set_type_float - if type == 'Integer' goto set_type_int - if type == 'Float' goto set_type_float - if type == 'Complex' goto set_type_complex - - set_type_int: - $P1 = '!matrixy_to_fortran_array_int'(a, rows, cols) - .return ($P1) - - set_type_float: - $P1 = '!matrixy_to_fortran_array_float'(a, rows, cols) - .return ($P1) - - set_type_complex: - $P1 = '!matrixy_to_fortran_array_complex'(a, rows, cols) - .return ($P1) -.end - -.sub '!fortran_to_matrixy_array' - .param pmc a - .param int rows - .param int cols - .param string type :optional - .param int has_type :opt_flag - - unless has_type goto set_type_float - if type == 'Integer' goto set_type_int - if type == 'Float' goto set_type_float - if type == 'Complex' goto set_type_complex - - set_type_int: - $P1 = '!fortran_to_matrixy_array_int'(a, rows, cols) - .return ($P1) - - set_type_float: - $P1 = '!fortran_to_matrixy_array_float'(a, rows, cols) - .return ($P1) - - set_type_complex: - $P1 = '!fortran_to_matrixy_array_complex'(a, rows, cols) - .return ($P1) -.end - -# float array conversion - -.sub '!matrixy_to_fortran_array_float' - .param pmc a - .param int rows - .param int cols - - .local int size - size = rows * cols - - .local pmc a_rma, a_n - a_rma = new 'ResizablePMCArray' - push a_rma, .DATATYPE_DOUBLE - push a_rma, size - push a_rma, 0 - - a_n = new 'ManagedStruct', a_rma - - #say 'matrixy -> fortran' - - .local int i, j, n - i = -1 - next_i: - i = i + 1 - unless i < rows goto return_array - j = -1 - next_j: - j = j + 1 - unless j < cols goto next_i - n = j * rows - n = n + i - $P0 = a[i;j] - $N0 = $P0 - #.say_indexes(i, j, n, $N0) - a_n[0;n] = $N0 - goto next_j - - return_array: - .return (a_n) - -.end - -.sub '!fortran_to_matrixy_array_float' - .param pmc a - .param int rows - .param int cols - - .local int size - size = rows * cols - - .local pmc A - A = new 'ResizablePMCArray' - - #say 'fortran -> matrixy' - - .local int i, j, n - i = -1 - next_i: - i = i + 1 - unless i < rows goto return_array - $P0 = new 'ResizablePMCArray' - $P0 = cols - push A, $P0 - j = -1 - next_j: - j = j + 1 - unless j < cols goto next_i - n = j * rows - n = n + i - $N0 = a[0;n] - #.say_indexes(i, j, n, $N0) - A[i;j] = $N0 - goto next_j - - return_array: - .return (A) - -.end - - - -# int array conversion - -.sub '!matrixy_to_fortran_array_int' - .param pmc a - .param int rows - .param int cols - - .local int size - size = rows * cols - - .local pmc a_rma, a_n - a_rma = new 'ResizablePMCArray' - push a_rma, .DATATYPE_INT - push a_rma, size - push a_rma, 0 - - a_n = new 'ManagedStruct', a_rma - - #say 'matrixy -> fortran' - - .local int i, j, n - i = -1 - next_i: - i = i + 1 - unless i < rows goto return_array - j = -1 - next_j: - j = j + 1 - unless j < cols goto next_i - n = j * rows - n = n + i - $P0 = a[i;j] - $I0 = $P0 - #.say_indexes(i, j, n, $I0) - a_n[0;n] = $I0 - goto next_j - - return_array: - .return (a_n) - -.end - -.sub '!fortran_to_matrixy_array_int' - .param pmc a - .param int rows - .param int cols - - .local int size - size = rows * cols - - .local pmc A - A = new 'ResizablePMCArray' - - #say 'fortran -> matrixy' - - .local int i, j, n - i = -1 - next_i: - i = i + 1 - unless i < rows goto return_array - $P0 = new 'ResizablePMCArray' - $P0 = cols - push A, $P0 - j = -1 - next_j: - j = j + 1 - unless j < cols goto next_i - n = j * rows - n = n + i - $I0 = a[0;n] - #.say_indexes(i, j, n, $I0) - A[i;j] = $I0 - goto next_j - - return_array: - .return (A) - -.end - - -# complex array conversion - -.sub '!matrixy_to_fortran_array_complex' - .param pmc a - .param int rows - .param int cols - - .local int size - size = rows * cols - - # see https://trac.parrot.org/parrot/ticket/486 - unless size == 1 goto skip_ums_bug_workaround - size = 2 - - skip_ums_bug_workaround: - .local pmc a_rma, a_umc, a_n - a_rma = new 'ResizablePMCArray' - push a_rma, .DATATYPE_DOUBLE - push a_rma, 0 - push a_rma, 0 - push a_rma, .DATATYPE_DOUBLE - push a_rma, 0 - push a_rma, 0 - a_umc = new 'UnManagedStruct', a_rma - - .local pmc a_rma_outer - a_rma_outer = new 'ResizablePMCArray' - push a_rma_outer, .DATATYPE_STRUCT - $P0 = a_rma_outer[-1] - setprop $P0, "_struct", a_umc - push a_rma_outer, size - push a_rma_outer, 0 - - a_n = new 'ManagedStruct', a_rma_outer - - #say 'matrixy -> fortran' - - .local int i, j, n - i = -1 - next_i: - i = i + 1 - unless i < rows goto return_array - j = -1 - next_j: - j = j + 1 - unless j < cols goto next_i - n = j * rows - n = n + i - $P0 = a[i;j] - $S0 = typeof $P0 - if $S0 == 'Complex' goto extract_complex - - extract_num: - $N0 = $P0 - $N1 = 0 - goto set_struct - - extract_complex: - $N0 = $P0["real"] - $N1 = $P0["imag"] - - set_struct: - #.say_indexes(i, j, n, $N0) - #.say_indexes(i, j, n, $N1) - a_n[0;n;0] = $N0 - a_n[0;n;1] = $N1 - goto next_j - - return_array: - .return (a_n) - -.end - -.sub '!fortran_to_matrixy_array_complex' - .param pmc a - .param int rows - .param int cols - - .local int size - size = rows * cols - - .local pmc A - A = new 'ResizablePMCArray' - - #say 'fortran -> matrixy' - - .local int i, j, n - i = -1 - next_i: - i = i + 1 - unless i < rows goto return_array - $P0 = new 'ResizablePMCArray' - $P0 = cols - push A, $P0 - j = -1 - next_j: - j = j + 1 - unless j < cols goto next_i - n = j * rows - n = n + i - $N0 = a[0;n;0] - $N1 = a[0;n;1] - #.say_indexes(i, j, n, $N0) - #.say_indexes(i, j, n, $N1) - $P0 = new 'Complex' - $P0["real"] = $N0 - $P0["imag"] = $N1 - A[i;j] = $P0 - goto next_j - - return_array: - .return (A) - -.end - - diff --git a/src/import_cblas_library.m b/src/import_cblas_library.m deleted file mode 100644 index 5d154aa..0000000 --- a/src/import_cblas_library.m +++ /dev/null @@ -1,9 +0,0 @@ -arch = computer; - -libpath = sprintf("extern/lib/%s/cblas", arch); -signatures = [ ... - '["f2c_dgemm","itt333pp3p3pp3",{"6":{"type":"fadr"},"7":{"type":"fadr"},"9":{"type":"fadr"},"11":{"type":"fadr"},"12":{"type":"fadr","out":1}}]' ... - ;'["f2c_zgemm","itt333pp3p3pp3",{"6":{"type":"fadc"},"7":{"type":"fadc"},"9":{"type":"fadc"},"11":{"type":"fadc"},"12":{"type":"fadc","out":1}}]' ... - ]; -loadlibrary(libpath, signatures, 'CBLAS'); - diff --git a/src/import_clapack_library.m b/src/import_clapack_library.m deleted file mode 100644 index 66cc913..0000000 --- a/src/import_clapack_library.m +++ /dev/null @@ -1,13 +0,0 @@ -arch = computer; - -libpath = sprintf("extern/lib/%s/clapack", arch); -signatures = [ ... - '["dgetrf_","i33p3p3",{"3":{"type":"fadr","out":1},"5":{"type":"fai","out":1},"6":{"out":1}}]' ... - ;'["dgetri_","i3p3pp33",{"2":{"type":"fadr","out":1},"4":{"type":"fai"},"5":{"type":"fadr","out":1},"7":{"out":1}}]' ... - %;"zgetrf_;i33p3p3" ... - %;"zgetri_;i3p3pp33" ... - ]; -loadlibrary(libpath, signatures, 'CLAPACK'); - - - diff --git a/src/pmc/nummatrix2d.pmc b/src/pmc/nummatrix2d.pmc index 7cba0bf..f84f622 100644 --- a/src/pmc/nummatrix2d.pmc +++ b/src/pmc/nummatrix2d.pmc @@ -45,8 +45,39 @@ resize_matrix(PARROT_INTERP, PMC * self, INTVAL row, INTVAL col) mem_sys_free(old_s); } +/* If the matrix is lazily transposed, actually transpose the physical memory + layout. This is necessary for calculations, especially BLAS calculations, + which aren't lazy-transpose-aware. */ static void -init_from_pmc_array(PARROT_INTERP, PMC * self, INTVAL rows_size, INTVAL cols_size, PMC * values) { +normalize_lazy_transpose(PARROT_INTERP, PMC * self) +{ + Parrot_NumMatrix2D_attributes * const attrs = PARROT_NUMMATRIX2D(self); + + if (IS_TRANSPOSED(attrs->flags)) { + const INTVAL rows_size = attrs->rows; + const INTVAL cols_size = attrs->cols; + const INTVAL size = rows_size * cols_size; + FLOATVAL * const new_s = ALLOCATE_STORAGE(size); + FLOATVAL * const old_s = attrs->storage; + INTVAL i, j; + + for (i = 0; i < rows_size; ++i) { + for (j = 0; j < cols_size; ++j) { + ITEM_XY_COLMAJOR(new_s, rows_size, cols_size, i, j) = + ITEM_XY_ROWMAJOR(old_s, rows_size, cols_size, i, j); + } + } + attrs->storage = new_s; + mem_sys_free(old_s); + FLAG_CLEAR(attrs->flags, FLAG_TRANSPOSED); + } +} + +/* Initialize the PMC from an array, filling the matrix row-at-a-time */ +static void +init_from_pmc_array(PARROT_INTERP, PMC * self, INTVAL rows_size, + INTVAL cols_size, PMC * values) +{ Parrot_NumMatrix2D_attributes * const attrs = PARROT_NUMMATRIX2D(self); FLOATVAL * s; INTVAL self_rows, self_cols, i, j, num = 0; @@ -68,6 +99,23 @@ init_from_pmc_array(PARROT_INTERP, PMC * self, INTVAL rows_size, INTVAL cols_siz } } +static void +add_scalar_float(PARROT_INTERP, PMC * self, FLOATVAL v) +{ + Parrot_NumMatrix2D_attributes * const attrs = PARROT_NUMMATRIX2D(self); + const INTVAL rows_size = attrs->rows; + const INTVAL cols_size = attrs->cols; + FLOATVAL * const s = attrs->storage; + INTVAL i, j; + + /* TODO: See if BLAS has a routine to do this */ + for (j = 0; j < cols_size; j++) { + for (i = 0; i < rows_size; i++) { + ITEM_XY_ROWMAJOR(s, rows_size, cols_size, i, j) += v; + } + } +} + pmclass NumMatrix2D dynpmc auto_attrs provides matrix { ATTR FLOATVAL * storage; ATTR INTVAL rows; @@ -259,87 +307,50 @@ pmclass NumMatrix2D dynpmc auto_attrs provides matrix { return pstr; } +/* + +=item* add + +=cut + +*/ + MULTI PMC *add(NumMatrix2D *value, PMC *dest) { int i = 0, j = 0; - INTVAL rows_size, cols_size; Parrot_NumMatrix2D_attributes * const selfattr = PARROT_NUMMATRIX2D(SELF); Parrot_NumMatrix2D_attributes * const valattr = PARROT_NUMMATRIX2D(value); Parrot_NumMatrix2D_attributes * destattr; + const INTVAL rows_size = selfattr->rows; + const INTVAL cols_size = selfattr->cols; + const INTVAL storage_size = rows_size * cols_size; - rows_size = selfattr->rows; - cols_size = selfattr->cols; - - if (rows_size != valattr->rows || cols_size != valattr->cols) { - /* XXX: Throw a better exception. */ + if (rows_size != valattr->rows || cols_size != valattr->cols) Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS, "NumMatrix2D: Matrix dimensions must match in add."); - } - - if ((IS_TRANSPOSED(selfattr->flags) && ! IS_TRANSPOSED(valattr->flags)) - || (IS_TRANSPOSED(valattr->flags) && ! IS_TRANSPOSED(selfattr->flags))) { - FLOATVAL *sstor = selfattr->storage, - *vstor = valattr->storage; - FLOATVAL *dstor = NULL; - - dest = Parrot_pmc_new(interp, VTABLE_type(interp, pmc)); - resize_matrix(interp, dest, rows_size - 1, cols_size - 1); - destattr = (Parrot_NumMatrix2D_attributes *) PARROT_NUMMATRIX2D(dest); - dstor = destattr->storage; - - if (IS_TRANSPOSED(selfattr->flags)) { - for (i = 0; i < rows_size; ++i) { - for (j = 0; j < cols_size; ++j) { - ITEM_XY_ROWMAJOR(dstor, rows_size, cols_size, i, j) = - ITEM_XY_COLMAJOR(sstor, rows_size, cols_size, i, j) - + ITEM_XY_ROWMAJOR(vstor, rows_size, cols_size, i, j); - } - } - } - else { - for (i = 0; i < rows_size; ++i) { - for (j = 0; j < cols_size; ++j) { - ITEM_XY_ROWMAJOR(dstor, rows_size, cols_size, i, j) = - ITEM_XY_ROWMAJOR(sstor, rows_size, cols_size, i, j) - + ITEM_XY_COLMAJOR(vstor, rows_size, cols_size, i, j); - } - } - } - } - else { - dest = VTABLE_clone(INTERP, value); - destattr = (Parrot_NumMatrix2D_attributes *) PARROT_NUMMATRIX2D(dest); - - cblas_daxpy(rows_size*cols_size, 1, selfattr->storage, 1, destattr->storage, 1); - } + normalize_lazy_transpose(INTERP, SELF); + normalize_lazy_transpose(INTERP, value); + dest = VTABLE_clone(INTERP, value); + destattr = PARROT_NUMMATRIX2D(dest); + cblas_daxpy(storage_size, 1, selfattr->storage, 1, destattr->storage, 1); return dest; } - MULTI PMC *add(Float *value, PMC *dest) { + MULTI PMC *add(DEFAULT *value, PMC *dest) { const FLOATVAL v = VTABLE_get_number(INTERP, value); - Parrot_NumMatrix2D_attributes * const attrs = PARROT_NUMMATRIX2D(SELF); - Parrot_NumMatrix2D_attributes * dest_attrs; - const INTVAL rows_size = attrs->rows; - const INTVAL cols_size = attrs->cols; - FLOATVAL * const s = attrs->storage; - FLOATVAL * dest_s; - INTVAL i, j; - - dest = Parrot_pmc_new(INTERP, SELF->vtable->base_type); - resize_matrix(INTERP, dest, rows_size - 1, cols_size - 1); - dest_attrs = PARROT_NUMMATRIX2D(dest); - dest_s = dest_attrs->storage; - - /* TODO: See if BLAS has a routine to do this */ - for (j = 0; j < cols_size; j++) { - for (i = 0; i < rows_size; i++) { - ITEM_XY_ROWMAJOR(dest_s, rows_size, cols_size, i, j) = - ITEM_XY_ROWMAJOR(s, rows_size, cols_size, i, j) + v; - } - } + dest = VTABLE_clone(INTERP, SELF); + add_scalar_float(INTERP, dest, v); return dest; } +/* + +=item* multiply + +=cut + +*/ + MULTI PMC *multiply(NumMatrix2D *value, PMC *dest) { INTVAL rows_size = 0, cols_size = 0, sflags = 0, vflags = 0; diff --git a/src/pmc/pla_matrix_types.h b/src/pmc/pla_matrix_types.h index 37f58d6..71a4355 100644 --- a/src/pmc/pla_matrix_types.h +++ b/src/pmc/pla_matrix_types.h @@ -148,6 +148,9 @@ do { \ (FLAG_UTRIANGLE) | \ (FLAG_TRIDIAGONAL) +#define FLAG_SET(f, i) ((f) |= (i)) +#define FLAG_CLEAR(f, i) ((f) &= ~((INTVAL)(i))) + /* Logical flag checking macros */ #define IS_GENERAL(flags) ((! (flags))) #define IS_TINY(flags) (((flags) & (FLAG_TINY))) diff --git a/t/harness b/t/harness index 4b5a395..7b1acf7 100644 --- a/t/harness +++ b/t/harness @@ -1,7 +1,7 @@ #! parrot-nqp INIT { - pir::load_bytecode('kakapo_full.pbc'); + pir::load_bytecode('library/kakapo_full.pbc'); Nqp::compile_file('t/testlib/matrixtest.nqp'); } diff --git a/t/run_test b/t/run_test index 493c80a..b81c1eb 100644 --- a/t/run_test +++ b/t/run_test @@ -1,4 +1,6 @@ #! parrot-nqp +our @ARGS; +main(@ARGS); INIT { pir::load_bytecode('./library/kakapo_full.pbc'); @@ -6,22 +8,23 @@ INIT { pir::loadlib__ps("./linalg_group"); } -class MyProgram is Program { +#class MyProgram is Program { method main(*@args) { - for @args { - my $test := $_; + #for @args { + my $test := "nummatrix2d.t"; my $sub := Nqp::compile_file("t/pmc/" ~ $test); $sub[0](); - } + #} } -} +#} -INIT { - Program::instance( - MyProgram.new( :from_parrot ) - ); -} +#INIT { + #Program::instance( + # MyProgram.new( :from_parrot ) + #); +#} + +#Program::instance().run; -Program::instance().run; diff --git a/t/sanity.t b/t/sanity.t index 59f4fec..3de8a32 100644 --- a/t/sanity.t +++ b/t/sanity.t @@ -9,12 +9,12 @@ INIT { MAIN(); sub MAIN() { - my $proto := Opcode::get_root_global(pir::get_namespace__P().get_name); - $proto.suite.run; + my $proto := Opcode::get_root_global(pir::get_namespace__P().get_name); + $proto.suite.run; } method test_load_linalg_group() { - my $pla := pir::loadlib__ps("./linalg_group"); + my $pla := pir::loadlib__ps("./dynext/linalg_group"); assert_not_instance_of($pla, "Undef", "Cannot load PLA library, linalg_group"); } diff --git a/tools/nci/h_to_pir.pl b/tools/nci/h_to_pir.pl deleted file mode 100644 index 412433c..0000000 --- a/tools/nci/h_to_pir.pl +++ /dev/null @@ -1,184 +0,0 @@ -=head1 DESCRIPTION - -This utility converts a C header file created using f2c into a pir library and an nci -signature file. - -The output nci file contains signatures that currently need adding to the parrot call list -/config/gen/call_list/misc.in. - - -h_to_dll.pl --name clapack --headerfile ./extern/include/clapack.h - --outputpir ./extern/pir/clapack.pir --outputnci ./extern/pir/clapack.nci - [--libsymformat "f2c_%s"] [--ncihints ./extern/include/clapack.hints] - -=cut - - -use strict; -use File::Basename; -use File::Path; -use Getopt::Long; - -my $output_pir; -my $nci_signatures; -my $name; -my $header_file; -my $symformat = '%s_'; # if given prefixes external symbol with prefix -my $nci_hints_file; - -GetOptions("headerfile=s" => \$header_file, "name=s" => \$name, - "outputpir=s" => \$output_pir, "outputnci=s" => \$nci_signatures, - "libsymformat=s" => \$symformat, "ncihints=s" => \$nci_hints_file); - -die "h_to_dll.pl --name clapack --headerfile ./extern/include/clapack.h --outputpir ./extern/pir/clapack.pir --outputnci ./extern/pir/clapack.nci" - if (!-f $header_file || $name eq '' || $output_pir eq '' || $nci_signatures eq ''); - - -# note: L_fp ~ function pointer, for now leave as pmc -my %nci_typemap = qw( -int i -integer* 3 -integer i -logical* 3 -char* t -real* p -real f -doublereal* p -doublereal d -complex* p -doublecomplex* p -VOID v -void v -L_fp p -); - -sub get_nci_code { - die "Can't find type '$_[0]'!" if not exists $nci_typemap{$_[0]}; - return $nci_typemap{$_[0]}; -} - -my %nci_hints; -if (-f $nci_hints_file) { - open my $fh, $nci_hints_file or die "cannot open file: $!"; - while (my $line = <$fh>) { - my ($fname, $fsig) = ( $line =~ m/^(\S+):(\S+)\r?$/); - $nci_hints{$fname} = $fsig; - } - close $fh; -} - -my %nci_sigs; - -my @pir_raw_funcs; -my @pir_raw_header; - -push @pir_raw_header, <) { - -#last if $c++ == 5; - -$rec =~ s/\n/ /mg; -$rec =~ s/\s+/ /mg; - -my ($ret, $fname, $args) = $rec =~ m/^(?:.* |)(\S+) (\S+)_\((.*)\).*$/s; - -# there's a better way to check if we reach the end! -last if $fname eq ''; - -push @pir_raw_funcs, - qq|.sub '$fname'|; - -my $nci_sig = get_nci_code($ret); -my @dlargs; -foreach my $arg (split(/,/, $args)) { - my ($ftype, $mod, $pname) = $arg =~ m/^\s*(\S+)\s+(\**)\s*(\S+)\s*$/; - $nci_sig .= get_nci_code($ftype.$mod); - push @pir_raw_funcs, qq| .param pmc $pname|; - push @dlargs, $pname; -} - -# override signature if in hints -if (exists $nci_hints{$fname}) { - $nci_sig = $nci_hints{$fname}; -} - -my $symbolname = sprintf($symformat, $fname); - -push @pir_raw_header, <$output_pir" or die "cannot open file: $!"; -print $fh join("\n", @pir_raw_header, "\n", @pir_raw_funcs, "\n"); -close $fh; - -open my $fh, ">$nci_signatures" or die "cannot open file: $!"; -print $fh join("\n", keys(%nci_sigs), "\n"); -close $fh; diff --git a/tools/nci/lib_to_dll.pl b/tools/nci/lib_to_dll.pl deleted file mode 100644 index b9a7545..0000000 --- a/tools/nci/lib_to_dll.pl +++ /dev/null @@ -1,154 +0,0 @@ -=head1 DESCRIPTION - -This utility converts a static library file for Windows (.lib) to a -dynamic link library (.dll). - -This utility should be run using a Visual Studio command shell as it requires -lib.exe, dumpbin.exe and cl.exe to be in the %PATH%. - -Specifying "--debug" will generate debug binaries. - -lib_to_dll.pl [--debug] --libdir "C:\CLAPACK-3.1.1-VisualStudio\LIB\Win32" --name clapackd - --olib libf2c.lib --olib BLAS.lib [--outdir=c:\out] - -=cut - -use strict; -use File::Basename; -use File::Path; -use Getopt::Long; - -my $debug = ''; -my $LIBDIR = ''; -my @otherlibs; -my $name = ''; -my $outdir = ''; - -my $tempdir = $ENV{'TEMP'}; - -GetOptions("libdir=s" => \$LIBDIR, "name=s" => \$name, "debug" => \$debug, "olib=s" => \@otherlibs, "outdir=s" => \$outdir); - -die 'Usage: lib_to_dll.pl [--debug] --libdir "C:\CLAPACK-3.1.1-VisualStudio\LIB\Win32" --name clapackd' - if (! -d $LIBDIR || $name eq ''); - -chdir($outdir) if -d $outdir; - -my $config = $debug ? 'DEBUG' : 'RELEASE'; - -my $workdir = "$tempdir\\lib_to_dll\\$config"; -mkpath($workdir); - -my $C = "$workdir\\$name.c"; -my $DEF = "$workdir\\$name.def"; -my $CL = "$workdir\\$name.args"; - -my $LIB = "$LIBDIR\\$name.lib"; - -my $OTHERLIBS; -for my $olib (@otherlibs) { - $OTHERLIBS .= qq("$LIBDIR\\$olib"\n); -} - -my $LIBEXE = 'lib.exe'; -my $DUMPBINEXE = 'dumpbin.exe'; -my $CLEXE = 'cl.exe'; - -my $c_data = <<'EOL'; -#include -BOOL WINAPI DllMain( HMODULE hModule, - DWORD ul_reason_for_call, - LPVOID lpReserved - ) -{ - switch (ul_reason_for_call) - { - case DLL_PROCESS_ATTACH: - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - case DLL_PROCESS_DETACH: - break; - } - return TRUE; -} -EOL - -my $switches = $debug ? qq(/MT /ZI /Zp8) : qq(/MT /GL /Zp8); - -my $generation_switches = qq(/EHsc /GF /Gy /Gm- /GS- /GR- /GA /GT /Gd); -my $preprocessor_switches = qq(/D_WIN32_WINNT=0x0500 /DWINVER=0x0500 /D_WIN32_IE=0x0501 /DWIN32_LEAN_AND_MEAN=1 /DSECURITY_WIN32=1 /D_CRT_SECURE_NO_DEPRECATE=1 /D_CRT_NONSTDC_NO_DEPRECATE=1); - -my $cl_data = <) { - chomp($objfile); - my $outfile = "$workdir\\$objfile"; - my $dirname = dirname($outfile); - mkpath($dirname); - - my $cmd = qq("$LIBEXE" /nologo /extract:"$objfile" /out:"$outfile" "$LIB"); - qx($cmd); - - $cl_data .= qq("$outfile"\n); - -} -close $objh; - -$cl_data .= <) { - chomp($member); - - if ($member =~ /public symbols/) { - $reached_public_symbols = 1; - next; - } - - next unless $reached_public_symbols; - - if ($member =~ /^\s+(\S+)\s+(\S+)\s*$/) { - next if $2 =~ /^\?\?_C@/; - next if $2 =~ /^\?/; # ignore c++ for now - next if $2 =~ /@/; - - my ($symbol) = $2 =~ /^_(\S+)$/; - - $def_data .= "$symbol\n"; - } -} -close $objh; - -# create the files -open my $fh, ">$C"; -print $fh $c_data; -close $fh; - -open my $fh, ">$DEF"; -print $fh $def_data; -close $fh; - -open my $fh, ">$CL"; -print $fh $cl_data; -close $fh; - -system(qq($CLEXE \@"$CL")); - - - - - -