diff --git a/build/program.rdi b/build/program.rdi index ef5c9f1..7c89379 100644 Binary files a/build/program.rdi and b/build/program.rdi differ diff --git a/eigsol_gpu.sublime-project b/eigsol_gpu.sublime-project new file mode 100644 index 0000000..22827c7 --- /dev/null +++ b/eigsol_gpu.sublime-project @@ -0,0 +1,11 @@ +{ + "folders": + [ + { + "path": "." + }, + { + "path": "src" + } + ] +} diff --git a/eigsol_gpu.sublime-workspace b/eigsol_gpu.sublime-workspace new file mode 100644 index 0000000..cebe612 --- /dev/null +++ b/eigsol_gpu.sublime-workspace @@ -0,0 +1,304 @@ +{ + "auto_complete": + { + "selected_items": + [ + ] + }, + "buffers": + [ + { + "contents": "#include \n\n// ---\n// Header includes\n#include \"base/base_inc.h\"\n#include \"os/os_inc.h\"\n\n\n// CUDA headers\n#include \"kernels.h\"\n\n// ---\n// .C includes\n#include \"base/base_inc.c\"\n#include \"os/os_inc.c\"\n#include \"os/os_entry_point.c\"\n\n\n#define grid_file_path_bin \"D:\\\\dev\\\\eigsol_gpu\\\\out\\\\grid.bin\"\n#define grid_file_path \"D:\\\\dev\\\\eigsol_gpu\\\\out\\\\grid.dat\"\n\nglobal U32 enable_logging = 1;\n\n// Complex number with double precision\ntypedef struct Z64 Z64;\nstruct Z64\n{\n F64 re;\n F64 im;\n};\n\ntypedef struct Grid Grid;\nstruct Grid \n{\n F64 start;\n F64 end;\n U32 num_steps;\n F64 *points;\n};\n\n\ntypedef struct BSplineCtx BSplineCtx;\nstruct BSplineCtx \n{\n U32 order;\n U32 num_knotpoints;\n U32 num_bsplines;\n U32 num_phys_points;\n};\n\n\n\n//~ Globals\nglobal BSplineCtx bspline_ctx = {0};\n\n//~ Functions\n\nfunction inline void\nlogger_debug(String8 msg)\n{\n OutputDebugString(msg.str);\n}\n\n#define LOG(msg) if(enable_logging) { logger_debug(msg) };\n\n\nfunction void\nwrite_array_binary_F64(String8 path_to_file, F64 *values, U32 array_size) \n{\n OS_Handle file_handle = OS_file_open(OS_AccessFlag_Write | OS_AccessFlag_CreateNew, \n path_to_file);\n { \n ArenaTemp scratch = scratch_get(0, 0);\n String8List list = {0};\n String8 temp = {0};\n temp.str = (U8*)values;\n temp.size = sizeof(F64)*array_size;\n str8_list_push(scratch.arena, &list, temp);\n OS_file_write(scratch.arena, file_handle, 0, list, 0);\n \n String8List log_list = {0};\n str8_list_push(scratch.arena, &log_list, str8_lit(\"Wrote binary array data to\"));\n str8_list_push(scratch.arena, &log_list, path_to_file);\n StringJoin join = {0};\n join.sep = str8_lit(\" \");\n join.post = str8_lit(\"\\n\");\n String8 log_msg = str8_list_join(scratch.arena, log_list, &join);\n OutputDebugString(log_msg.str);\n }\n OS_file_close(file_handle);\n}\n\nfunction void\nwrite_array_F64(String8 path_to_file, F64 *values, U32 array_size, char* fmt) \n{\n OS_Handle file_handle = OS_file_open(OS_AccessFlag_Write | OS_AccessFlag_CreateNew, \n path_to_file);\n {\n ArenaTemp scratch = scratch_get(0, 0);\n String8List list = {0};\n for(U32 i = 0; i < array_size; i++) \n {\n str8_list_pushf(scratch.arena, &list, fmt, values[i]);\n }\n OS_file_write(scratch.arena, file_handle, 0, list, 0);\n \n String8List log_list = {0};\n str8_list_push(scratch.arena, &log_list, str8_lit(\"Wrote array to\"));\n str8_list_push(scratch.arena, &log_list, path_to_file);\n StringJoin join = {0};\n join.sep = str8_lit(\" \");\n join.post = str8_lit(\"\\n\");\n String8 log_msg = str8_list_join(scratch.arena, log_list, &join);\n OutputDebugString(log_msg.str);\n }\n OS_file_close(file_handle);\n \n}\n\n\n\nfunction\nvoid EntryPoint() \n{\n OS_InitReceipt os_receipt = OS_init();\n OS_InitGfxReceipt os_gfx_receipt = OS_gfx_init(os_receipt);\n\n Arena *arena = m_make_arena();\n\n Grid grid = {0};\n grid.start = 0.0;\n grid.end = 10.0;\n grid.num_steps = 1000;\n \n grid.points = PushArrayZero(arena, F64, grid.num_steps);\n F64 step_size = (grid.end-grid.start)/(F64)grid.num_steps;\n grid.points[0] = grid.start;\n grid.points[grid.num_steps-1] = grid.end;\n for(U32 i = 1; i < grid.num_steps-1; i++)\n {\n grid.points[i] = grid.points[i-1] + step_size;\n }\n\n write_array_binary_F64(str8_lit(grid_file_path_bin), grid.points, grid.num_steps);\n write_array_F64(str8_lit(grid_file_path), grid.points, grid.num_steps, \"%13.6e\\n\");\n \n // Create bsplines\n U32 k = 4;\n U32 N = 14;\n bspline_ctx.order = k; \n bspline_ctx.num_knotpoints = N; \n U32 num_bsplines = N-k;\n U32 num_phys_points = N-2*k+2; // Remove k points at each end, and then add back the first and last points.\n\n\n\n}\n\n\n", + "file": "src/main.c", + "file_size": 3834, + "file_write_time": 133732027810885494, + "settings": + { + "buffer_size": 3679, + "encoding": "UTF-8", + "line_ending": "Windows" + } + } + ], + "build_system": "Packages/C++/C Single File.sublime-build", + "build_system_choices": + [ + [ + [ + [ + "Packages/C++/C Single File.sublime-build", + "" + ], + [ + "Packages/C++/C Single File.sublime-build", + "Run" + ] + ], + [ + "Packages/C++/C Single File.sublime-build", + "" + ] + ] + ], + "build_varint": "", + "command_palette": + { + "height": 0.0, + "last_filter": "", + "selected_items": + [ + [ + "View", + "View Package File" + ], + [ + "Color", + "Colorsublime: Install Theme" + ], + [ + "Pack", + "Package Control: Install Package" + ], + [ + "Install Pack", + "Package Control: Install Package" + ], + [ + "Package Insta", + "Package Control: Install Package" + ], + [ + "Color Sch", + "UI: Select Color Scheme" + ], + [ + "Install Pac", + "Package Control: Install Package" + ], + [ + "Package", + "Install Package Control" + ], + [ + "View ", + "View Package File" + ] + ], + "width": 0.0 + }, + "console": + { + "height": 0.0, + "history": + [ + ] + }, + "distraction_free": + { + "menu_visible": true, + "show_minimap": false, + "show_open_files": false, + "show_tabs": false, + "side_bar_visible": false, + "status_bar_visible": false + }, + "expanded_folders": + [ + "/W/eigsol_gpu", + "/W/eigsol_gpu/src" + ], + "file_history": + [ + "/C/Users/anton/AppData/Roaming/Sublime Text 3/Packages/Default/Default (Windows).sublime-keymap", + "/C/sbs/sb1/java/guidesign/src/com/comsol/guidesign/views/%USER%", + "/C/Users/antonlj/AppData/Roaming/Sublime Text 3/Packages/Colorsublime/Colorsublime.sublime-settings", + "/C/Users/antonlj/AppData/Roaming/Sublime Text 3/Packages/User/Colorsublime.sublime-settings", + "/C/sbs/sb1/java/guidesign/src/com/comsol/guidesign/actions/DesignCreatorActionFactory.java", + "/C/sbs/sb1/java/design/src/com/comsol/design/operations/DesignOperation.java", + "/C/Users/antonlj/AppData/Roaming/Sublime Text 3/Packages/Default/symbol.py", + "/C/Program Files/Sublime Text 3/Packages/Default.sublime-package", + "/C/Users/antonlj/AppData/Roaming/Sublime Text 3/Packages/User/Preferences.sublime-settings", + "/C/sbs/sb1/java/testgui/src/com/comsol/testgui/builder/TBuilderFeatures.java", + "/C/Users/antonlj/AppData/Roaming/Sublime Text 3/Packages/Default/Preferences.sublime-settings" + ], + "find": + { + "height": 40.0 + }, + "find_in_files": + { + "height": 103.333333333, + "where_history": + [ + ] + }, + "find_state": + { + "case_sensitive": false, + "find_history": + [ + "main.c" + ], + "highlight": true, + "in_selection": false, + "preserve_case": false, + "regex": false, + "replace_history": + [ + ], + "reverse": false, + "show_context": true, + "use_buffer2": true, + "whole_word": false, + "wrap": true + }, + "groups": + [ + { + "selected": 0, + "sheets": + [ + { + "buffer": 0, + "file": "src/main.c", + "semi_transient": false, + "settings": + { + "buffer_size": 3679, + "regions": + { + }, + "selection": + [ + [ + 2699, + 2699 + ] + ], + "settings": + { + "syntax": "Packages/C++/C.sublime-syntax", + "tab_size": 2, + "translate_tabs_to_spaces": true + }, + "translation.x": 0.0, + "translation.y": 1552.0, + "zoom_level": 1.0 + }, + "stack_index": 0, + "type": "text" + } + ] + } + ], + "incremental_find": + { + "height": 25.0 + }, + "input": + { + "height": 0.0 + }, + "layout": + { + "cells": + [ + [ + 0, + 0, + 1, + 1 + ] + ], + "cols": + [ + 0.0, + 1.0 + ], + "rows": + [ + 0.0, + 1.0 + ] + }, + "menu_visible": true, + "output.exec": + { + "height": 267.0 + }, + "output.find_results": + { + "height": 0.0 + }, + "pinned_build_system": "", + "project": "eigsol_gpu.sublime-project", + "replace": + { + "height": 46.0 + }, + "save_all_on_build": true, + "select_file": + { + "height": 0.0, + "last_filter": "", + "selected_items": + [ + [ + "main", + "src\\main.c" + ], + [ + "BuilderInf", + "design\\src\\com\\comsol\\design\\util\\link\\BuilderInfoVisitor.java" + ], + [ + "DesignPhysicsM", + "design\\src\\com\\comsol\\design\\DesignPhysicsMaker.java" + ], + [ + "TBuilderFeat", + "testgui\\src\\com\\comsol\\testgui\\builder\\TBuilderFeatures.java" + ] + ], + "width": 0.0 + }, + "select_project": + { + "height": 0.0, + "last_filter": "", + "selected_items": + [ + ], + "width": 0.0 + }, + "select_symbol": + { + "height": 392.0, + "last_filter": "DesignPhysicsMak", + "selected_items": + [ + [ + "DesignPhysicsMak", + "DesignPhysicsMaker" + ], + [ + "DeviceModelFeatu", + "DeviceModelFeatureOperation" + ] + ], + "width": 644.0 + }, + "selected_group": 0, + "settings": + { + }, + "show_minimap": false, + "show_open_files": false, + "show_tabs": true, + "side_bar_visible": false, + "side_bar_width": 145.0, + "status_bar_visible": true, + "template_settings": + { + } +} diff --git a/out/Bspline3.dat b/out/Bspline3.dat new file mode 100644 index 0000000..848914b --- /dev/null +++ b/out/Bspline3.dat @@ -0,0 +1,1000 @@ + 0.000000e+00 + 3.658667e-06 + 2.926933e-05 + 9.878400e-05 + 2.341547e-04 + 4.573333e-04 + 7.902720e-04 + 1.254923e-03 + 1.873237e-03 + 2.667168e-03 + 3.658667e-03 + 4.869685e-03 + 6.322176e-03 + 8.038091e-03 + 1.003938e-02 + 1.234800e-02 + 1.498590e-02 + 1.797503e-02 + 2.133734e-02 + 2.509479e-02 + 2.926933e-02 + 3.388291e-02 + 3.895748e-02 + 4.451500e-02 + 5.057741e-02 + 5.716667e-02 + 6.430473e-02 + 7.201354e-02 + 8.031505e-02 + 8.923122e-02 + 9.878400e-02 + 1.089953e-01 + 1.198872e-01 + 1.314815e-01 + 1.438002e-01 + 1.568653e-01 + 1.706984e-01 + 1.852913e-01 + 2.005836e-01 + 2.165093e-01 + 2.330027e-01 + 2.499978e-01 + 2.674288e-01 + 2.852298e-01 + 3.033351e-01 + 3.216787e-01 + 3.401947e-01 + 3.588174e-01 + 3.774809e-01 + 3.961192e-01 + 4.146667e-01 + 4.330573e-01 + 4.512253e-01 + 4.691047e-01 + 4.866298e-01 + 5.037347e-01 + 5.203535e-01 + 5.364203e-01 + 5.518694e-01 + 5.666348e-01 + 5.806507e-01 + 5.938512e-01 + 6.061705e-01 + 6.175428e-01 + 6.279021e-01 + 6.371827e-01 + 6.453186e-01 + 6.522440e-01 + 6.578930e-01 + 6.621999e-01 + 6.650987e-01 + 6.665235e-01 + 6.664127e-01 + 6.647733e-01 + 6.616693e-01 + 6.571667e-01 + 6.513312e-01 + 6.442289e-01 + 6.359254e-01 + 6.264867e-01 + 6.159787e-01 + 6.044671e-01 + 5.920178e-01 + 5.786968e-01 + 5.645698e-01 + 5.497027e-01 + 5.341613e-01 + 5.180116e-01 + 5.013193e-01 + 4.841504e-01 + 4.665707e-01 + 4.486460e-01 + 4.304422e-01 + 4.120251e-01 + 3.934607e-01 + 3.748147e-01 + 3.561530e-01 + 3.375415e-01 + 3.190461e-01 + 3.007325e-01 + 2.826667e-01 + 2.649144e-01 + 2.475417e-01 + 2.306142e-01 + 2.141979e-01 + 1.983587e-01 + 1.831623e-01 + 1.686746e-01 + 1.549524e-01 + 1.419952e-01 + 1.297813e-01 + 1.182887e-01 + 1.074954e-01 + 9.737951e-02 + 8.791902e-02 + 7.909200e-02 + 7.087650e-02 + 6.325057e-02 + 5.619226e-02 + 4.967961e-02 + 4.369067e-02 + 3.820349e-02 + 3.319612e-02 + 2.864660e-02 + 2.453299e-02 + 2.083333e-02 + 1.752567e-02 + 1.458806e-02 + 1.199855e-02 + 9.735179e-03 + 7.776000e-03 + 6.099061e-03 + 4.682411e-03 + 3.504096e-03 + 2.542165e-03 + 1.774667e-03 + 1.179648e-03 + 7.351573e-04 + 4.192427e-04 + 2.099520e-04 + 8.533333e-05 + 2.343467e-05 + 2.304000e-06 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 diff --git a/out/knotpoints.dat b/out/knotpoints.dat new file mode 100644 index 0000000..038ede1 --- /dev/null +++ b/out/knotpoints.dat @@ -0,0 +1,35 @@ + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 0.000000e+00 + 3.571429e-01 + 7.142857e-01 + 1.071429e+00 + 1.428571e+00 + 1.785714e+00 + 2.142857e+00 + 2.500000e+00 + 2.857143e+00 + 3.214286e+00 + 3.571429e+00 + 3.928571e+00 + 4.285714e+00 + 4.642857e+00 + 5.000000e+00 + 5.357143e+00 + 5.714286e+00 + 6.071429e+00 + 6.428571e+00 + 6.785714e+00 + 7.142857e+00 + 7.500000e+00 + 7.857143e+00 + 8.214286e+00 + 8.571429e+00 + 8.928571e+00 + 9.285714e+00 + 9.642857e+00 + 1.000000e+01 + 1.000000e+01 + 1.000000e+01 + 1.000000e+01 diff --git a/py_notebook/EigsolGPU_test.ipynb b/py_notebook/EigsolGPU_test.ipynb index bad0722..8cdea9c 100644 --- a/py_notebook/EigsolGPU_test.ipynb +++ b/py_notebook/EigsolGPU_test.ipynb @@ -2,23 +2,23 @@ "cells": [ { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "id": "1d08e1d3-0f62-467e-8217-9eaf458afeb4", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "[]" + "[]" ] }, - "execution_count": 5, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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", + "image/png": "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n/9Z06ZNU3Fxsc466yz98Y9/dLsszzFNU9dff73mzp2r4uJinXrqqfrBD35wwvub4Pj+8Ic/6NJLL9XMmTNlGIZ+8YtfjPi+bdtas2aNZsyYoeLiYtXX1+vPf/5zRmrL2zCyefNmNTU1ae3atdq1a5cWLlyoJUuW6MCBA26X5hlPP/20Vq5cqeeee05bt27V4OCgLr74YvX19bldmme98MIL+tGPfqSzzz7b7VI856OPPtL555+vgoIC/eY3v9Frr72mO+64Q1OmTHG7NM+55ZZbdM899+juu+/W66+/rltuuUW33nqr7rrrLrdLy2l9fX1auHChNmzYMOr3b731Vt15551qaWnR888/rwkTJmjJkiU6cuRI+ouz89TixYvtlStXxr42TdOeOXOm3dzc7GJV3nbgwAFbkv3000+7XYon9fT02Keffrq9detW+4ILLrBXrVrldkmecs0119h/8zd/43YZeeGSSy6xv/GNb4x47stf/rJ9xRVXuFSR90iyH3300djXlmXZFRUV9m233RZ77tChQ3YwGLQffPDBtNeTl52RcDisnTt3qr6+Pvacz+dTfX29tm/f7mJl3tbV1SVJmjp1qsuVeNPKlSt1ySWXjPi9Rur88pe/VE1Njf7pn/5J5eXlOuecc7Rx40a3y/Kk8847T62trXrzzTclSS+99JKeeeYZ/e3f/q3LlXnXO++8o/b29hH/fpSVlam2tjYjn4s5caO8VOvs7JRpmgqFQiOeD4VCeuONN1yqytssy9JVV12l888/XwsWLHC7HM956KGHtGvXLr3wwgtul+JZb7/9tu655x41NTXpO9/5jl544QV9+9vfVmFhoZYvX+52eZ5y7bXXqru7W/PmzZPf75dpmrrxxht1xRVXuF2aZ7W3t0vSqJ+LzvfSKS/DCDJv5cqVeuWVV/TMM8+4XYrntLW1adWqVdq6dauKiorcLsezLMtSTU2NbrrpJknSOeeco1deeUUtLS2EkRT77//+b/3sZz/TAw88oE9+8pPavXu3rrrqKs2cOZP32qPycphm+vTp8vv96ujoGPF8R0eHKioqXKrKuxobG/XrX/9aTz31lGbPnu12OZ6zc+dOHThwQJ/61KcUCAQUCAT09NNP684771QgEJBpmm6X6AkzZszQ/PnzRzx35plnau/evS5V5F3//u//rmuvvVaXX365zjrrLH3961/X1VdfrebmZrdL8yzns8+tz8W8DCOFhYVatGiRWltbY89ZlqXW1lbV1dW5WJm32LatxsZGPfroo/r973+vuXPnul2SJ33+85/Xyy+/rN27d8ceNTU1uuKKK7R79275/X63S/SE888//5il6W+++aZOPvlklyryrv7+fvl8Iz+e/H6/LMtyqSLvmzt3rioqKkZ8LnZ3d+v555/PyOdi3g7TNDU1afny5aqpqdHixYu1fv169fX1qaGhwe3SPGPlypV64IEH9Nhjj6m0tDQ27lhWVqbi4mKXq/OO0tLSY+bhTJgwQdOmTWN+TgpdffXVOu+883TTTTfpq1/9qnbs2KF7771X9957r9ulec6ll16qG2+8UXPmzNEnP/lJvfjii1q3bp2+8Y1vuF1aTuvt7dVbb70V+/qdd97R7t27NXXqVM2ZM0dXXXWVbrjhBp1++umaO3eurr/+es2cOVOXXXZZ+otL+3qdLHbXXXfZc+bMsQsLC+3Fixfbzz33nNsleYqkUR//9V//5XZpnsfS3vT41a9+ZS9YsMAOBoP2vHnz7Hvvvdftkjypu7vbXrVqlT1nzhy7qKjIPuWUU+zrrrvOHhgYcLu0nPbUU0+N+m/y8uXLbduOLO+9/vrr7VAoZAeDQfvzn/+8vWfPnozUZtg2W9oBAAD35OWcEQAAkD0IIwAAwFWEEQAA4CrCCAAAcBVhBAAAuIowAgAAXEUYAQAAriKMAAAAVxFGAACAqwgjAADAVYQRAADgKsIIAABw1f8DG70qd78mvu8AAAAASUVORK5CYII=", "text/plain": [ "
" ] @@ -36,9 +36,13 @@ "\n", "\n", "grid_bin = np.fromfile(\"../out/grid.bin\", dtype=np.float64)\n", - "plt.plot(grid_bin, grid_bin)\n", + "plt.plot(grid_bin, np.zeros(len(grid_bin)))\n", "grid = np.loadtxt(\"../out/grid.dat\")\n", - "plt.plot(grid, grid, linestyle='--')" + "plt.plot(grid, np.zeros(len(grid)), linestyle='--')\n", + "knots = np.loadtxt(\"../out/knotpoints.dat\")\n", + "plt.plot(knots, np.zeros(len(knots)), marker='o')\n", + "bspline3 = np.loadtxt(\"../out/Bspline3.dat\")\n", + "plt.plot(grid, bspline3)\n" ] }, { diff --git a/src/main.c b/src/main.c index 7a31579..d515771 100644 --- a/src/main.c +++ b/src/main.c @@ -18,22 +18,57 @@ #define grid_file_path_bin "D:\\dev\\eigsol_gpu\\out\\grid.bin" #define grid_file_path "D:\\dev\\eigsol_gpu\\out\\grid.dat" +#define knotpoints_file_path "D:\\dev\\eigsol_gpu\\out\\knotpoints.dat" + +global U32 enable_logging = 1; + +// Complex number with double precision +typedef struct Z64 Z64; +struct Z64 +{ + F64 re; + F64 im; +}; typedef struct Grid Grid; -struct Grid { +struct Grid +{ F64 start; F64 end; U32 num_steps; F64 *points; }; + typedef struct BSplineCtx BSplineCtx; -struct BSplineCtx { +struct BSplineCtx +{ + Arena* arena; U32 order; + F64 *knotpoints; + U32 num_knotpoints; + U32 num_bsplines; + U32 num_phys_points; }; -void write_array_binary_F64(String8 path_to_file, F64 *values, U32 array_size) + +//~ Globals +global BSplineCtx g_bspline_ctx = {0}; + +//~ Functions + +function inline void +logger_debug(String8 msg) +{ + OutputDebugString(msg.str); +} + +#define LOG(msg) if(enable_logging) { logger_debug(msg) }; + + +function void +write_array_binary_F64(String8 path_to_file, F64 *values, U32 array_size) { OS_Handle file_handle = OS_file_open(OS_AccessFlag_Write | OS_AccessFlag_CreateNew, path_to_file); @@ -45,12 +80,21 @@ void write_array_binary_F64(String8 path_to_file, F64 *values, U32 array_size) temp.size = sizeof(F64)*array_size; str8_list_push(scratch.arena, &list, temp); OS_file_write(scratch.arena, file_handle, 0, list, 0); + + String8List log_list = {0}; + str8_list_push(scratch.arena, &log_list, str8_lit("Wrote binary array data to")); + str8_list_push(scratch.arena, &log_list, path_to_file); + StringJoin join = {0}; + join.sep = str8_lit(" "); + join.post = str8_lit("\n"); + String8 log_msg = str8_list_join(scratch.arena, log_list, &join); + OutputDebugString(log_msg.str); } OS_file_close(file_handle); } - -void write_array_F64(String8 path_to_file, F64 *values, U32 array_size, char* fmt) +function void +write_array_F64(String8 path_to_file, F64 *values, U32 array_size, char* fmt) { OS_Handle file_handle = OS_file_open(OS_AccessFlag_Write | OS_AccessFlag_CreateNew, path_to_file); @@ -62,13 +106,56 @@ void write_array_F64(String8 path_to_file, F64 *values, U32 array_size, char* fm str8_list_pushf(scratch.arena, &list, fmt, values[i]); } OS_file_write(scratch.arena, file_handle, 0, list, 0); + + String8List log_list = {0}; + str8_list_push(scratch.arena, &log_list, str8_lit("Wrote array to")); + str8_list_push(scratch.arena, &log_list, path_to_file); + StringJoin join = {0}; + join.sep = str8_lit(" "); + join.post = str8_lit("\n"); + String8 log_msg = str8_list_join(scratch.arena, log_list, &join); + OutputDebugString(log_msg.str); } OS_file_close(file_handle); + +} + +function F64 bspline_recursion(F64 x, U32 k, U32 i) +{ + F64 *t = g_bspline_ctx.knotpoints; + + if(k == 1) + { + if(i < g_bspline_ctx.num_bsplines && x >= t[i] && x < t[i+1]) + { + return 1.0; + } else { + return 0.0; + } + } + else + { + F64 term1 = (x - t[i])/(t[i+k-1]-t[i])*bspline_recursion(x, k-1, i); + F64 term2 = (t[i+k]-x)/(t[i+k]-t[i+1])*bspline_recursion(x, k-1, i+1); + + return term1 + term2; + } + } -void EntryPoint() { +function F64 get_bspline_F64(F64 x_coord, U32 index) +{ + U32 k = g_bspline_ctx.order; + F64 out = bspline_recursion(x_coord, k, index); + return out; +} + + + function +void EntryPoint() +{ OS_InitReceipt os_receipt = OS_init(); OS_InitGfxReceipt os_gfx_receipt = OS_gfx_init(os_receipt); @@ -78,20 +165,68 @@ void EntryPoint() { grid.start = 0.0; grid.end = 10.0; grid.num_steps = 1000; - + grid.points = PushArrayZero(arena, F64, grid.num_steps); F64 step_size = (grid.end-grid.start)/(F64)grid.num_steps; grid.points[0] = grid.start; grid.points[grid.num_steps-1] = grid.end; - for(U32 i = 1; i < grid.num_steps-1; i++) { + for(U32 i = 1; i < grid.num_steps-1; i++) + { grid.points[i] = grid.points[i-1] + step_size; } write_array_binary_F64(str8_lit(grid_file_path_bin), grid.points, grid.num_steps); write_array_F64(str8_lit(grid_file_path), grid.points, grid.num_steps, "%13.6e\n"); - + + // Create knotpoint sequence. + U32 k = 4; + U32 N = 35; + g_bspline_ctx.order = k; + g_bspline_ctx.num_knotpoints = N; + g_bspline_ctx.num_bsplines = N-k; + g_bspline_ctx.num_phys_points = N-(2*k)+2; // Remove k points at each end, and then add back the first and last points. + g_bspline_ctx.arena = arena; + g_bspline_ctx.knotpoints = (F64*)PushArrayZero(arena, F64, g_bspline_ctx.num_knotpoints); + // Set up physical points; + F64 delta = (grid.end-grid.start)/(g_bspline_ctx.num_phys_points-1); + // Set ghost points including first physical + U32 phys_point_index = g_bspline_ctx.num_phys_points + k-1; + for(U32 i = 0; i < k; i++) + { + g_bspline_ctx.knotpoints[i] = grid.start; + } + for(U32 i = k; i < phys_point_index; i++) + { + g_bspline_ctx.knotpoints[i] = g_bspline_ctx.knotpoints[i-1] + delta; + } + // Set the last points + F64 last_physical = grid.end; + for(U32 i = phys_point_index; i < g_bspline_ctx.num_knotpoints; i++) + { + g_bspline_ctx.knotpoints[i] = last_physical; + } + + write_array_F64(str8_lit(knotpoints_file_path), g_bspline_ctx.knotpoints, g_bspline_ctx.num_knotpoints, "%13.6e\n"); + + + String8 Bspline3_fn = str8_lit("D:\\dev\\eigsol_gpu\\out\\Bspline3.dat"); + F64 *Bspline3 = (F64 *)PushArrayZero(arena, F64, grid.num_steps); + for(U32 i = 0; i < grid.num_steps; i++) + { + Bspline3[i] = get_bspline_F64(grid.points[i], 3); + } + + write_array_F64(Bspline3_fn, Bspline3, grid.num_steps, "%13.6e\n"); + + + + + + } + + diff --git a/timeBuild.ctm b/timeBuild.ctm index e7ef7ed..99b2bed 100644 Binary files a/timeBuild.ctm and b/timeBuild.ctm differ